aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog94
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/cgraph.c32
-rw-r--r--gcc/cgraph.h72
-rw-r--r--gcc/cgraphbuild.c59
-rw-r--r--gcc/cgraphclones.c11
-rw-r--r--gcc/cgraphunit.c17
-rw-r--r--gcc/ipa-comdats.c6
-rw-r--r--gcc/ipa-cp.c9
-rw-r--r--gcc/ipa-devirt.c3
-rw-r--r--gcc/ipa-inline-transform.c4
-rw-r--r--gcc/ipa-inline.c16
-rw-r--r--gcc/ipa-prop.c24
-rw-r--r--gcc/ipa-pure-const.c8
-rw-r--r--gcc/ipa-ref.c284
-rw-r--r--gcc/ipa-ref.h64
-rw-r--r--gcc/ipa-reference.c12
-rw-r--r--gcc/ipa-split.c2
-rw-r--r--gcc/ipa-utils.c6
-rw-r--r--gcc/ipa-visibility.c15
-rw-r--r--gcc/ipa.c33
-rw-r--r--gcc/lto-cgraph.c48
-rw-r--r--gcc/lto-streamer-in.c6
-rw-r--r--gcc/lto-streamer-out.c3
-rw-r--r--gcc/lto-streamer.h2
-rw-r--r--gcc/lto/lto-partition.c28
-rw-r--r--gcc/lto/lto-symtab.c4
-rw-r--r--gcc/symtab.c293
-rw-r--r--gcc/trans-mem.c8
-rw-r--r--gcc/tree-emutls.c2
-rw-r--r--gcc/tree-inline.c6
-rw-r--r--gcc/varpool.c17
32 files changed, 684 insertions, 506 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fd7bec2..e35a8fe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,97 @@
+2014-06-25 Martin Liska <mliska@suse.cz>
+
+ IPA REF refactoring
+ * Makefile.in: Removed header file (ipa-ref-inline.h).
+ * cgraph.c (cgraph_turn_edge_to_speculative): New IPA REF function
+ called.
+ (cgraph_speculative_call_info): Likewise.
+ (cgraph_for_node_thunks_and_aliases): Likewise.
+ (cgraph_for_node_and_aliases): Likewise.
+ (verify_cgraph_node): Likewise.
+ * cgraph.h: Batch of IPA REF functions become member functions of
+ symtab_node: add_reference, maybe_add_reference, clone_references,
+ clone_referring, clone_reference, find_reference,
+ remove_stmt_references, remove_all_references,
+ remove_all_referring, dump_references, dump_referring,
+ has_alias_p, iterate_reference, iterate_referring.
+ * cgraphbuild.c (record_reference): New IPA REF function used.
+ (record_type_list): Likewise.
+ (record_eh_tables): Likewise.
+ (mark_address): Likewise.
+ (mark_load): Likewise.
+ (mark_store): Likewise.
+ (pass_build_cgraph_edges): Likewise.
+ (rebuild_cgraph_edge): Likewise.
+ (cgraph_rebuild_references): Likewise.
+ (pass_remove_cgraph_callee_edges): Likewise.
+ * cgraphclones.c (cgraph_clone_node): Likewise.
+ (cgraph_create_virtual_clone): Likewise.
+ (cgraph_materialize_clone): Likewise.
+ (cgraph_materialize_all_clones): Likewise.
+ * cgraphunit.c (cgraph_reset_node): Likewise.
+ (cgraph_reset_node): Likewise.
+ (analyze_function): Likewise.
+ (assemble_thunks_and_aliases): Likewise.
+ (expand_function): Likewise.
+ * ipa-comdats.c (propagate_comdat_group): Likewise.
+ (enqueue_references): Likewise.
+ * ipa-cp.c (ipcp_discover_new_direct_edges): Likewise.
+ (create_specialized_node): Likewise.
+ * ipa-devirt.c (referenced_from_vtable_p): Likewise.
+ * ipa-inline-transform.c (can_remove_node_now_p_1): Likewise.
+ * ipa-inline.c (reset_edge_caches): Likewise.
+ (update_caller_keys): Likewise.
+ (execute): Likewise.
+ * ipa-prop.c (remove_described_reference): Likewise.
+ (propagate_controlled_uses): Likewise.
+ (ipa_edge_duplication_hook): Likewise.
+ (ipa_modify_call_arguments): Likewise.
+ * ipa-pure-const.c (propagate_pure_const): Likewise.
+ * ipa-ref-inline.h: Header file removed, functions moved
+ to symtab_node class.
+ * ipa-ref.c (remove_reference): New class member function.
+ (cannot_lead_to_return): New class member function.
+ (referring_ref_list): Likewise.
+ (referred_ref_list): Likewise.
+ Rest of functions moved to symtab_node class.
+ * ipa-ref.h: New member functions remove_reference,
+ cannot_lead_to_return, referring_ref_list, referred_ref_list added
+ to ipa_ref class.
+ ipa_ref_list class has new member functions: first_reference,
+ first_referring, clear, nreferences.
+ * ipa-reference.c (analyze_function): New IPA REF function used.
+ (write_node_summary_p): Likewise.
+ (ipa_reference_write_optimization_summary): Likewise.
+ * ipa-split.c (split_function): Likewise.
+ * ipa-utils.c (ipa_reverse_postorder): Likewise.
+ * ipa-visibility.c (cgraph_non_local_node_p_1): Likewise.
+ (function_and_variable_visibility): Likewise.
+ * ipa.c (has_addr_references_p): Likewise.
+ (process_references): Argument type changed.
+ (symtab_remove_unreachable_nodes): New IPA REF function used.
+ (process_references): Likewise.
+ (set_writeonly_bit): Likewise.
+ * lto-cgraph.c: Implementation of new symtab_node member functions
+ that uses new IPA REF functions.
+ * lto-streamer-in.c (fixup_call_stmt_edges_1): New IPA REF function used.
+ * lto-streamer-out.c (output_symbol_p): Likewise.
+ * lto-streamer.h (referenced_from_this_partition_p): Argument type
+ changed.
+ * lto/lto-partition.c (add_references_to_partition): New IPA REF function
+ used.
+ (add_symbol_to_partition_1): Likewise.
+ (lto_balanced_map): Likewise.
+ * lto/lto-symtab.c (lto_cgraph_replace_node): Likewise.
+ * symtab.c: Implementation of new IPA REF API.
+ * trans-mem.c (ipa_tm_create_version_alias): New IPA REF function used.
+ (ipa_tm_create_version): Likewise.
+ (ipa_tm_execute): Likewise.
+ * tree-emutls.c (gen_emutls_addr): Likewise.
+ * tree-inline.c (copy_bb): Likewise.
+ (delete_unreachable_blocks_update_callgraph): Likewise.
+ * varpool.c (varpool_remove_unreferenced_decls): Likewise.
+ (varpool_for_node_and_aliases): Likewise.
+
2014-06-25 Trevor Saunders <tsaunders@mozilla.com>
* config/i386/winnt.c (i386_find_on_wrapper_list): Fix typo.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5587b75..c950273 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -905,7 +905,7 @@ CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) double-int.h \
IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H)
IPA_REFERENCE_H = ipa-reference.h $(BITMAP_H) $(TREE_H)
CGRAPH_H = cgraph.h $(VEC_H) $(TREE_H) $(BASIC_BLOCK_H) $(FUNCTION_H) \
- cif-code.def ipa-ref.h ipa-ref-inline.h $(LINKER_PLUGIN_API_H) is-a.h
+ cif-code.def ipa-ref.h $(LINKER_PLUGIN_API_H) is-a.h
DF_H = df.h $(BITMAP_H) $(REGSET_H) sbitmap.h $(BASIC_BLOCK_H) \
alloc-pool.h $(TIMEVAR_H)
RESOURCE_H = resource.h hard-reg-set.h $(DF_H)
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index afd41b7..7360f77 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1101,7 +1101,7 @@ cgraph_turn_edge_to_speculative (struct cgraph_edge *e,
int direct_frequency)
{
struct cgraph_node *n = e->caller;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
struct cgraph_edge *e2;
if (dump_file)
@@ -1123,8 +1123,7 @@ cgraph_turn_edge_to_speculative (struct cgraph_edge *e,
e->count -= e2->count;
e->frequency -= e2->frequency;
cgraph_call_edge_duplication_hooks (e, e2);
- ref = ipa_record_reference (n, n2,
- IPA_REF_ADDR, e->call_stmt);
+ ref = n->add_reference (n2, IPA_REF_ADDR, e->call_stmt);
ref->lto_stmt_uid = e->lto_stmt_uid;
ref->speculative = e->speculative;
cgraph_mark_address_taken_node (n2);
@@ -1177,8 +1176,7 @@ cgraph_speculative_call_info (struct cgraph_edge *e,
indirect = e2;
reference = NULL;
- for (i = 0; ipa_ref_list_reference_iterate (&e->caller->ref_list,
- i, ref); i++)
+ for (i = 0; e->caller->iterate_reference (i, ref); i++)
if (ref->speculative
&& ((ref->stmt && ref->stmt == e->call_stmt)
|| (!ref->stmt && ref->lto_stmt_uid == e->lto_stmt_uid)))
@@ -1257,7 +1255,7 @@ cgraph_resolve_speculation (struct cgraph_edge *edge, tree callee_decl)
edge->frequency = CGRAPH_FREQ_MAX;
edge->speculative = false;
e2->speculative = false;
- ipa_remove_reference (ref);
+ ref->remove_reference ();
if (e2->indirect_unknown_callee || e2->inline_failed)
cgraph_remove_edge (e2);
else
@@ -2197,7 +2195,7 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node,
{
struct cgraph_edge *e;
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
if (callback (node, data))
return true;
@@ -2208,10 +2206,10 @@ 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; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
- struct cgraph_node *alias = ipa_ref_referring_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,
@@ -2232,14 +2230,14 @@ cgraph_for_node_and_aliases (struct cgraph_node *node,
bool include_overwritable)
{
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
if (callback (node, data))
return true;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
- struct cgraph_node *alias = ipa_ref_referring_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,
@@ -2843,15 +2841,14 @@ verify_cgraph_node (struct cgraph_node *node)
{
bool ref_found = false;
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
if (node->callees)
{
error ("Alias has call edges");
error_found = true;
}
- for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list,
- i, ref); i++)
+ for (i = 0; node->iterate_reference (i, ref); i++)
if (ref->use != IPA_REF_ALIAS)
{
error ("Alias has non-alias reference");
@@ -2897,7 +2894,7 @@ verify_cgraph_node (struct cgraph_node *node)
{
pointer_set_t *stmts = pointer_set_create ();
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
/* Reach the trees by walking over the CFG, and note the
enclosing basic-blocks in the call edges. */
@@ -2955,8 +2952,7 @@ verify_cgraph_node (struct cgraph_node *node)
}
}
for (i = 0;
- ipa_ref_list_reference_iterate (&node->ref_list, i, ref);
- i++)
+ node->iterate_reference (i, ref); i++)
if (ref->stmt && !pointer_set_contains (stmts, ref->stmt))
{
error ("reference to dead statement");
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index ce6b9e6..0761e26 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -189,6 +189,71 @@ public:
return x_section->name;
}
+ /* Return ipa reference from this symtab_node to
+ REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
+ of the use and STMT the statement (if it exists). */
+ struct ipa_ref *add_reference (symtab_node *referred_node,
+ enum ipa_ref_use use_type);
+
+ /* Return ipa reference from this symtab_node to
+ REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
+ of the use and STMT the statement (if it exists). */
+ struct ipa_ref *add_reference (symtab_node *referred_node,
+ enum ipa_ref_use use_type, gimple stmt);
+
+ /* If VAL is a reference to a function or a variable, add a reference from
+ this symtab_node to the corresponding symbol table node. USE_TYPE specify
+ type of the use and STMT the statement (if it exists). Return the new
+ reference or NULL if none was created. */
+ struct ipa_ref *maybe_add_reference (tree val, enum ipa_ref_use use_type,
+ gimple stmt);
+
+ /* Clone all references from symtab NODE to this symtab_node. */
+ void clone_references (symtab_node *node);
+
+ /* Remove all stmt references in non-speculative references.
+ Those are not maintained during inlining & clonning.
+ The exception are speculative references that are updated along
+ with callgraph edges associated with them. */
+ void clone_referring (symtab_node *node);
+
+ /* Clone reference REF to this symtab_node and set its stmt to STMT. */
+ struct ipa_ref *clone_reference (struct ipa_ref *ref, gimple stmt);
+
+ /* Find the structure describing a reference to REFERRED_NODE
+ and associated with statement STMT. */
+ struct ipa_ref *find_reference (symtab_node *, gimple, unsigned int);
+
+ /* Remove all references that are associated with statement STMT. */
+ void remove_stmt_references (gimple stmt);
+
+ /* Remove all stmt references in non-speculative references.
+ Those are not maintained during inlining & clonning.
+ The exception are speculative references that are updated along
+ with callgraph edges associated with them. */
+ void clear_stmts_in_references (void);
+
+ /* Remove all references in ref list. */
+ void remove_all_references (void);
+
+ /* Remove all referring items in ref list. */
+ void remove_all_referring (void);
+
+ /* Dump references in ref list to FILE. */
+ void dump_references (FILE *file);
+
+ /* Dump referring in list to FILE. */
+ void dump_referring (FILE *);
+
+ /* Return true if list contains an alias. */
+ bool has_aliases_p (void);
+
+ /* Iterates I-th reference in the list, REF is also set. */
+ struct ipa_ref *iterate_reference (unsigned i, struct ipa_ref *&ref);
+
+ /* Iterates I-th referring item in the list, REF is also set. */
+ struct ipa_ref *iterate_referring (unsigned i, struct ipa_ref *&ref);
+
/* Vectors of referring and referenced entities. */
struct ipa_ref_list ref_list;
@@ -1537,16 +1602,13 @@ varpool_all_refs_explicit_p (varpool_node *vnode)
/* Constant pool accessor function. */
htab_t constant_pool_htab (void);
-/* FIXME: inappropriate dependency of cgraph on IPA. */
-#include "ipa-ref-inline.h"
-
/* Return node that alias N is aliasing. */
static inline symtab_node *
symtab_alias_target (symtab_node *n)
{
- struct ipa_ref *ref;
- ipa_ref_list_reference_iterate (&n->ref_list, 0, ref);
+ struct ipa_ref *ref = NULL;
+ n->iterate_reference (0, ref);
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
return ref->referred;
}
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 6bdc8ca..bfc4495 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -82,17 +82,13 @@ record_reference (tree *tp, int *walk_subtrees, void *data)
struct cgraph_node *node = cgraph_get_create_node (decl);
if (!ctx->only_vars)
cgraph_mark_address_taken_node (node);
- ipa_record_reference (ctx->varpool_node,
- node,
- IPA_REF_ADDR, NULL);
+ ctx->varpool_node->add_reference (node, IPA_REF_ADDR);
}
if (TREE_CODE (decl) == VAR_DECL)
{
varpool_node *vnode = varpool_node_for_decl (decl);
- ipa_record_reference (ctx->varpool_node,
- vnode,
- IPA_REF_ADDR, NULL);
+ ctx->varpool_node->add_reference (vnode, IPA_REF_ADDR);
}
*walk_subtrees = 0;
break;
@@ -129,9 +125,7 @@ record_type_list (struct cgraph_node *node, tree list)
if (TREE_CODE (type) == VAR_DECL)
{
varpool_node *vnode = varpool_node_for_decl (type);
- ipa_record_reference (node,
- vnode,
- IPA_REF_ADDR, NULL);
+ node->add_reference (vnode, IPA_REF_ADDR);
}
}
}
@@ -150,7 +144,7 @@ record_eh_tables (struct cgraph_node *node, struct function *fun)
tree per_decl = DECL_FUNCTION_PERSONALITY (node->decl);
struct cgraph_node *per_node = cgraph_get_create_node (per_decl);
- ipa_record_reference (node, per_node, IPA_REF_ADDR, NULL);
+ node->add_reference (per_node, IPA_REF_ADDR);
cgraph_mark_address_taken_node (per_node);
}
@@ -231,18 +225,14 @@ mark_address (gimple stmt, tree addr, tree, void *data)
{
struct cgraph_node *node = cgraph_get_create_node (addr);
cgraph_mark_address_taken_node (node);
- ipa_record_reference ((symtab_node *)data,
- node,
- IPA_REF_ADDR, stmt);
+ ((symtab_node *)data)->add_reference (node, IPA_REF_ADDR, stmt);
}
else if (addr && TREE_CODE (addr) == VAR_DECL
&& (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
{
varpool_node *vnode = varpool_node_for_decl (addr);
- ipa_record_reference ((symtab_node *)data,
- vnode,
- IPA_REF_ADDR, stmt);
+ ((symtab_node *)data)->add_reference (vnode, IPA_REF_ADDR, stmt);
}
return false;
@@ -260,18 +250,14 @@ mark_load (gimple stmt, tree t, tree, void *data)
directly manipulated in the code. Pretend that it's an address. */
struct cgraph_node *node = cgraph_get_create_node (t);
cgraph_mark_address_taken_node (node);
- ipa_record_reference ((symtab_node *)data,
- node,
- IPA_REF_ADDR, stmt);
+ ((symtab_node *)data)->add_reference (node, IPA_REF_ADDR, stmt);
}
else if (t && TREE_CODE (t) == VAR_DECL
&& (TREE_STATIC (t) || DECL_EXTERNAL (t)))
{
varpool_node *vnode = varpool_node_for_decl (t);
- ipa_record_reference ((symtab_node *)data,
- vnode,
- IPA_REF_LOAD, stmt);
+ ((symtab_node *)data)->add_reference (vnode, IPA_REF_LOAD, stmt);
}
return false;
}
@@ -287,9 +273,7 @@ mark_store (gimple stmt, tree t, tree, void *data)
{
varpool_node *vnode = varpool_node_for_decl (t);
- ipa_record_reference ((symtab_node *)data,
- vnode,
- IPA_REF_STORE, stmt);
+ ((symtab_node *)data)->add_reference (vnode, IPA_REF_STORE, stmt);
}
return false;
}
@@ -375,22 +359,19 @@ pass_build_cgraph_edges::execute (function *fun)
&& gimple_omp_parallel_child_fn (stmt))
{
tree fn = gimple_omp_parallel_child_fn (stmt);
- ipa_record_reference (node,
- cgraph_get_create_node (fn),
- IPA_REF_ADDR, stmt);
+ node->add_reference (cgraph_get_create_node (fn),
+ IPA_REF_ADDR, stmt);
}
if (gimple_code (stmt) == GIMPLE_OMP_TASK)
{
tree fn = gimple_omp_task_child_fn (stmt);
if (fn)
- ipa_record_reference (node,
- cgraph_get_create_node (fn),
- IPA_REF_ADDR, stmt);
+ node->add_reference (cgraph_get_create_node (fn),
+ IPA_REF_ADDR, stmt);
fn = gimple_omp_task_copy_fn (stmt);
if (fn)
- ipa_record_reference (node,
- cgraph_get_create_node (fn),
- IPA_REF_ADDR, stmt);
+ node->add_reference (cgraph_get_create_node (fn),
+ IPA_REF_ADDR, stmt);
}
}
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -446,7 +427,7 @@ rebuild_cgraph_edges (void)
gimple_stmt_iterator gsi;
cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
node->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
@@ -492,13 +473,13 @@ cgraph_rebuild_references (void)
basic_block bb;
struct cgraph_node *node = cgraph_get_node (current_function_decl);
gimple_stmt_iterator gsi;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
int i;
/* Keep speculative references for further cgraph edge expansion. */
- for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref);)
+ for (i = 0; node->iterate_reference (i, ref);)
if (!ref->speculative)
- ipa_remove_reference (ref);
+ ref->remove_reference ();
else
i++;
@@ -588,7 +569,7 @@ pass_remove_cgraph_callee_edges::execute (function *)
{
struct cgraph_node *node = cgraph_get_node (current_function_decl);
cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
return 0;
}
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 6f83d74..d57cd9f 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -459,7 +459,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
for (e = n->indirect_calls; e; e = e->next_callee)
cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
count_scale, freq, update_original);
- ipa_clone_references (new_node, &n->ref_list);
+ new_node->clone_references (n);
new_node->next_sibling_clone = n->clones;
if (n->clones)
@@ -568,8 +568,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
|| in_lto_p)
new_node->unique_name = true;
FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
- ipa_maybe_record_reference (new_node, map->new_tree,
- IPA_REF_ADDR, NULL);
+ new_node->maybe_add_reference (map->new_tree, IPA_REF_ADDR, NULL);
if (!args_to_skip)
new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
else if (old_node->clone.combined_args_to_skip)
@@ -1035,7 +1034,7 @@ cgraph_materialize_clone (struct cgraph_node *node)
{
cgraph_release_function_body (node->clone_of);
cgraph_node_remove_callees (node->clone_of);
- ipa_remove_all_references (&node->clone_of->ref_list);
+ node->clone_of->remove_all_references ();
}
node->clone_of = NULL;
bitmap_obstack_release (NULL);
@@ -1120,10 +1119,10 @@ cgraph_materialize_all_clones (void)
if (!node->analyzed && node->callees)
{
cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
}
else
- ipa_clear_stmts_in_references (node);
+ node->clear_stmts_in_references ();
if (cgraph_dump_file)
fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
#ifdef ENABLE_CHECKING
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 1b7ab33..76b2fda1 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -393,7 +393,7 @@ cgraph_reset_node (struct cgraph_node *node)
node->cpp_implicit_alias = false;
cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
}
/* Return true when there are references to NODE. */
@@ -401,10 +401,10 @@ cgraph_reset_node (struct cgraph_node *node)
static bool
referred_to_p (symtab_node *node)
{
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
/* See if there are any references at all. */
- if (ipa_ref_list_referring_iterate (&node->ref_list, 0, ref))
+ if (node->iterate_referring (0, ref))
return true;
/* For functions check also calls. */
cgraph_node *cn = dyn_cast <cgraph_node *> (node);
@@ -1069,7 +1069,7 @@ analyze_functions (void)
next = next->same_comdat_group)
enqueue_node (next);
}
- for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_reference (i, ref); i++)
if (ref->referred->definition)
enqueue_node (ref->referred);
cgraph_process_new_functions ();
@@ -1712,7 +1712,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
{
struct cgraph_edge *e;
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
for (e = node->callers; e;)
if (e->caller->thunk.thunk_p)
@@ -1725,11 +1725,10 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
}
else
e = e->next_caller;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
- i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
- struct cgraph_node *alias = ipa_ref_referring_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
@@ -1852,7 +1851,7 @@ expand_function (struct cgraph_node *node)
/* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
points to the dead function body. */
cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
}
/* Node comparer that is responsible for the order that corresponds
diff --git a/gcc/ipa-comdats.c b/gcc/ipa-comdats.c
index b1bc35e..f9e1ad8 100644
--- a/gcc/ipa-comdats.c
+++ b/gcc/ipa-comdats.c
@@ -72,7 +72,7 @@ propagate_comdat_group (struct symtab_node *symbol,
/* Walk all references to SYMBOL, recursively dive into aliases. */
for (i = 0;
- ipa_ref_list_referring_iterate (&symbol->ref_list, i, ref)
+ symbol->iterate_referring (i, ref)
&& newgroup != error_mark_node; i++)
{
struct symtab_node *symbol2 = ref->referring;
@@ -161,9 +161,9 @@ enqueue_references (symtab_node **first,
symtab_node *symbol)
{
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
- for (i = 0; ipa_ref_list_reference_iterate (&symbol->ref_list, i, ref); i++)
+ for (i = 0; symbol->iterate_reference (i, ref); i++)
{
symtab_node *node = symtab_alias_ultimate_target (ref->referred, NULL);
if (!node->aux && node->definition)
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 33ff9b6..04e88b5 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -2387,14 +2387,12 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
fprintf (dump_file, " controlled uses count of param "
"%i bumped down to %i\n", param_index, c);
if (c == 0
- && (to_del = ipa_find_reference (node,
- cs->callee,
- NULL, 0)))
+ && (to_del = node->find_reference (cs->callee, NULL, 0)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " and even removing its "
"cloning-created reference\n");
- ipa_remove_reference (to_del);
+ to_del->remove_reference ();
}
}
}
@@ -2803,8 +2801,7 @@ create_specialized_node (struct cgraph_node *node,
args_to_skip, "constprop");
ipa_set_node_agg_value_chain (new_node, aggvals);
for (av = aggvals; av; av = av->next)
- ipa_maybe_record_reference (new_node, av->value,
- IPA_REF_ADDR, NULL);
+ new_node->maybe_add_reference (av->value, IPA_REF_ADDR, NULL);
if (dump_file && (dump_flags & TDF_DETAILS))
{
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 604b809..21f4f11 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -686,8 +686,7 @@ referenced_from_vtable_p (struct cgraph_node *node)
if (cgraph_state <= CGRAPH_STATE_CONSTRUCTION)
return true;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
- i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if ((ref->use == IPA_REF_ALIAS
&& referenced_from_vtable_p (cgraph (ref->referring)))
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 4cfd87b..03442fc 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -86,7 +86,7 @@ can_remove_node_now_p_1 (struct cgraph_node *node)
can remove its offline copy, but we would need to keep unanalyzed node in
the callgraph so references can point to it. */
return (!node->address_taken
- && !ipa_ref_has_aliases_p (&node->ref_list)
+ && !node->has_aliases_p ()
&& !node->used_as_abstract_origin
&& cgraph_can_remove_if_no_direct_calls_p (node)
/* Inlining might enable more devirtualizing, so we want to remove
@@ -451,7 +451,7 @@ inline_transform (struct cgraph_node *node)
next = e->next_callee;
cgraph_redirect_edge_call_stmt_to_callee (e);
}
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
timevar_push (TV_INTEGRATION);
if (node->callees && optimize)
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 82bbd7f..81030f3 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1120,7 +1120,7 @@ reset_edge_caches (struct cgraph_node *node)
struct cgraph_edge *e = node->callees;
struct cgraph_node *where = node;
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
if (where->global.inlined_to)
where = where->global.inlined_to;
@@ -1131,10 +1131,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; ipa_ref_list_referring_iterate (&where->ref_list,
- i, ref); i++)
+ for (i = 0; where->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
- reset_edge_caches (ipa_ref_referring_node (ref));
+ reset_edge_caches (dyn_cast <cgraph_node *> (ref->referring));
if (!e)
return;
@@ -1174,7 +1173,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
{
struct cgraph_edge *edge;
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
if ((!node->alias && !inline_summary (node)->inlinable)
|| node->global.inlined_to)
@@ -1182,11 +1181,10 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
if (!bitmap_set_bit (updated_nodes, node->uid))
return;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
- i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
- struct cgraph_node *alias = ipa_ref_referring_node (ref);
+ struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for);
}
@@ -2430,7 +2428,7 @@ pass_early_inline::execute (function *fun)
#ifdef ENABLE_CHECKING
verify_cgraph_node (node);
#endif
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
/* Even when not optimizing or not inlining inline always-inline
functions. */
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index d9dca52..5f5bf89 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2806,12 +2806,12 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
origin = rdesc->cs;
if (!origin)
return false;
- to_del = ipa_find_reference (origin->caller, symbol,
- origin->call_stmt, origin->lto_stmt_uid);
+ to_del = origin->caller->find_reference (symbol, origin->call_stmt,
+ origin->lto_stmt_uid);
if (!to_del)
return false;
- ipa_remove_reference (to_del);
+ to_del->remove_reference ();
if (dump_file)
fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n",
xstrdup (origin->caller->name ()),
@@ -3209,8 +3209,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
if (t && TREE_CODE (t) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
&& (n = cgraph_get_node (TREE_OPERAND (t, 0)))
- && (ref = ipa_find_reference (new_root,
- n, NULL, 0)))
+ && (ref = new_root->find_reference (n, NULL, 0)))
{
if (dump_file)
fprintf (dump_file, "ipa-prop: Removing cloning-created "
@@ -3218,7 +3217,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
xstrdup (new_root->name ()),
new_root->order,
xstrdup (n->name ()), n->order);
- ipa_remove_reference (ref);
+ ref->remove_reference ();
}
}
}
@@ -3249,8 +3248,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
&& IPA_NODE_REF (clone)->ipcp_orig_node)
{
struct ipa_ref *ref;
- ref = ipa_find_reference (clone,
- n, NULL, 0);
+ ref = clone->find_reference (n, NULL, 0);
if (ref)
{
if (dump_file)
@@ -3261,7 +3259,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
clone->order,
xstrdup (n->name ()),
n->order);
- ipa_remove_reference (ref);
+ ref->remove_reference ();
}
clone = clone->callers->caller;
}
@@ -3455,10 +3453,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
struct ipa_ref *ref;
symtab_node *n = cgraph_node_for_jfunc (src_jf);
gcc_checking_assert (n);
- ref = ipa_find_reference (src->caller, n,
- src->call_stmt, src->lto_stmt_uid);
+ ref = src->caller->find_reference (n, src->call_stmt,
+ src->lto_stmt_uid);
gcc_checking_assert (ref);
- ipa_clone_ref (ref, dst->caller, ref->stmt);
+ dst->caller->clone_reference (ref, ref->stmt);
gcc_checking_assert (ipa_refdesc_pool);
struct ipa_cst_ref_desc *dst_rdesc
@@ -3899,7 +3897,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
len = adjustments.length ();
vargs.create (len);
callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
- ipa_remove_stmt_references (current_node, stmt);
+ current_node->remove_stmt_references (stmt);
gsi = gsi_for_stmt (stmt);
prev_gsi = gsi;
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index b9a3d3e..a074a11 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -1138,7 +1138,7 @@ propagate_pure_const (void)
struct cgraph_edge *e;
struct cgraph_edge *ie;
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
funct_state w_l = get_function_state (w);
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1263,7 +1263,7 @@ propagate_pure_const (void)
break;
/* And finally all loads and stores. */
- for (i = 0; ipa_ref_list_reference_iterate (&w->ref_list, i, ref); i++)
+ for (i = 0; w->iterate_reference (i, ref); i++)
{
enum pure_const_state_e ref_state = IPA_CONST;
bool ref_looping = false;
@@ -1271,14 +1271,14 @@ propagate_pure_const (void)
{
case IPA_REF_LOAD:
/* readonly reads are safe. */
- if (TREE_READONLY (ipa_ref_varpool_node (ref)->decl))
+ if (TREE_READONLY (ref->referred->decl))
break;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " nonreadonly global var read\n");
ref_state = IPA_PURE;
break;
case IPA_REF_STORE:
- if (ipa_ref_cannot_lead_to_return (ref))
+ if (ref->cannot_lead_to_return ())
break;
ref_state = IPA_NEITHER;
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c
index df84c9c..1be173a 100644
--- a/gcc/ipa-ref.c
+++ b/gcc/ipa-ref.c
@@ -27,294 +27,60 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "ipa-utils.h"
-static const char *ipa_ref_use_name[] = {"read","write","addr","alias"};
-
-/* Return ipa reference from REFERING_NODE or REFERING_VARPOOL_NODE
- to REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
- of the use and STMT the statement (if it exists). */
-
-struct ipa_ref *
-ipa_record_reference (symtab_node *referring_node,
- symtab_node *referred_node,
- enum ipa_ref_use use_type, gimple stmt)
-{
- struct ipa_ref *ref, *ref2;
- struct ipa_ref_list *list, *list2;
- ipa_ref_t *old_references;
-
- gcc_checking_assert (!stmt || is_a <cgraph_node *> (referring_node));
- gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt);
-
- list = &referring_node->ref_list;
- old_references = vec_safe_address (list->references);
- vec_safe_grow (list->references, vec_safe_length (list->references) + 1);
- ref = &list->references->last ();
-
- list2 = &referred_node->ref_list;
- list2->referring.safe_push (ref);
- ref->referred_index = list2->referring.length () - 1;
- ref->referring = referring_node;
- ref->referred = referred_node;
- ref->stmt = stmt;
- ref->lto_stmt_uid = 0;
- ref->use = use_type;
- ref->speculative = 0;
-
- /* If vector was moved in memory, update pointers. */
- if (old_references != list->references->address ())
- {
- int i;
- for (i = 0; ipa_ref_list_reference_iterate (list, i, ref2); i++)
- ipa_ref_referred_ref_list (ref2)->referring[ref2->referred_index] = ref2;
- }
- return ref;
-}
-
-/* If VAL is a reference to a function or a variable, add a reference from
- REFERRING_NODE to the corresponding symbol table node. USE_TYPE specify
- type of the use and STMT the statement (if it exists). Return the new
- reference or NULL if none was created. */
-
-struct ipa_ref *
-ipa_maybe_record_reference (symtab_node *referring_node, tree val,
- enum ipa_ref_use use_type, gimple stmt)
-{
- STRIP_NOPS (val);
- if (TREE_CODE (val) != ADDR_EXPR)
- return NULL;
- val = get_base_var (val);
- if (val && (TREE_CODE (val) == FUNCTION_DECL
- || TREE_CODE (val) == VAR_DECL))
- {
- symtab_node *referred = symtab_get_node (val);
- gcc_checking_assert (referred);
- return ipa_record_reference (referring_node, referred,
- use_type, stmt);
- }
- return NULL;
-}
-
-/* Remove reference REF. */
+/* Remove reference. */
void
-ipa_remove_reference (struct ipa_ref *ref)
+ipa_ref::remove_reference ()
{
- struct ipa_ref_list *list = ipa_ref_referred_ref_list (ref);
- struct ipa_ref_list *list2 = ipa_ref_referring_ref_list (ref);
+ struct ipa_ref_list *list = referred_ref_list ();
+ struct ipa_ref_list *list2 = referring_ref_list ();
vec<ipa_ref_t, va_gc> *old_references = list2->references;
struct ipa_ref *last;
- gcc_assert (list->referring[ref->referred_index] == ref);
+ gcc_assert (list->referring[referred_index] == this);
last = list->referring.last ();
- if (ref != last)
+ if (this != last)
{
- list->referring[ref->referred_index] = list->referring.last ();
- list->referring[ref->referred_index]->referred_index
- = ref->referred_index;
+ list->referring[referred_index] = list->referring.last ();
+ list->referring[referred_index]->referred_index
+ = referred_index;
}
list->referring.pop ();
last = &list2->references->last ();
+
+ struct ipa_ref *ref = this;
+
if (ref != last)
{
*ref = *last;
- ipa_ref_referred_ref_list (ref)->referring[ref->referred_index] = ref;
+ referred_ref_list ()->referring[referred_index] = ref;
}
list2->references->pop ();
gcc_assert (list2->references == old_references);
}
-/* Remove all references in ref list LIST. */
-
-void
-ipa_remove_all_references (struct ipa_ref_list *list)
-{
- while (vec_safe_length (list->references))
- ipa_remove_reference (&list->references->last ());
- vec_free (list->references);
-}
-
-/* Remove all references in ref list LIST. */
-
-void
-ipa_remove_all_referring (struct ipa_ref_list *list)
-{
- while (list->referring.length ())
- ipa_remove_reference (list->referring.last ());
- list->referring.release ();
-}
-
-/* Dump references in LIST to FILE. */
-
-void
-ipa_dump_references (FILE * file, struct ipa_ref_list *list)
-{
- struct ipa_ref *ref;
- int i;
- for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
- {
- fprintf (file, "%s/%i (%s)",
- ref->referred->asm_name (),
- ref->referred->order,
- ipa_ref_use_name [ref->use]);
- if (ref->speculative)
- fprintf (file, " (speculative)");
- }
- fprintf (file, "\n");
-}
-
-/* Dump referring in LIST to FILE. */
-
-void
-ipa_dump_referring (FILE * file, struct ipa_ref_list *list)
-{
- struct ipa_ref *ref;
- int i;
- for (i = 0; ipa_ref_list_referring_iterate (list, i, ref); i++)
- {
- fprintf (file, "%s/%i (%s)",
- ref->referring->asm_name (),
- ref->referring->order,
- ipa_ref_use_name [ref->use]);
- if (ref->speculative)
- fprintf (file, " (speculative)");
- }
- fprintf (file, "\n");
-}
-
-/* Clone reference REF to DEST_NODE and set its stmt to STMT. */
-
-struct ipa_ref *
-ipa_clone_ref (struct ipa_ref *ref,
- symtab_node *dest_node,
- gimple stmt)
-{
- bool speculative = ref->speculative;
- unsigned int stmt_uid = ref->lto_stmt_uid;
- struct ipa_ref *ref2;
-
- ref2 = ipa_record_reference (dest_node,
- ref->referred,
- ref->use, stmt);
- ref2->speculative = speculative;
- ref2->lto_stmt_uid = stmt_uid;
- return ref2;
-}
-
-/* Clone all references from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
+/* Return true when execution of reference can lead to return from
+ function. */
-void
-ipa_clone_references (symtab_node *dest_node,
- struct ipa_ref_list *src)
-{
- struct ipa_ref *ref, *ref2;
- int i;
- for (i = 0; ipa_ref_list_reference_iterate (src, i, ref); i++)
- {
- bool speculative = ref->speculative;
- unsigned int stmt_uid = ref->lto_stmt_uid;
-
- ref2 = ipa_record_reference (dest_node,
- ref->referred,
- ref->use, ref->stmt);
- ref2->speculative = speculative;
- ref2->lto_stmt_uid = stmt_uid;
- }
-}
-
-/* Clone all referring from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
-
-void
-ipa_clone_referring (symtab_node *dest_node,
- struct ipa_ref_list *src)
-{
- struct ipa_ref *ref, *ref2;
- int i;
- for (i = 0; ipa_ref_list_referring_iterate (src, i, ref); i++)
- {
- bool speculative = ref->speculative;
- unsigned int stmt_uid = ref->lto_stmt_uid;
-
- ref2 = ipa_record_reference (ref->referring,
- dest_node,
- ref->use, ref->stmt);
- ref2->speculative = speculative;
- ref2->lto_stmt_uid = stmt_uid;
- }
-}
-
-/* Return true when execution of REF can lead to return from
- function. */
bool
-ipa_ref_cannot_lead_to_return (struct ipa_ref *ref)
+ipa_ref::cannot_lead_to_return ()
{
- return cgraph_node_cannot_return (ipa_ref_referring_node (ref));
-}
-
-/* Return true if list contains an alias. */
-bool
-ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list)
-{
- struct ipa_ref *ref;
- int i;
-
- for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++)
- if (ref->use == IPA_REF_ALIAS)
- return true;
- return false;
+ return cgraph_node_cannot_return (dyn_cast <cgraph_node *> (referring));
}
-/* Find the structure describing a reference in REFERRING_NODE to REFERRED_NODE
- and associated with statement STMT. */
+/* Return reference list this reference is in. */
-struct ipa_ref *
-ipa_find_reference (symtab_node *referring_node, symtab_node *referred_node,
- gimple stmt, unsigned int lto_stmt_uid)
+struct ipa_ref_list *
+ipa_ref::referring_ref_list (void)
{
- struct ipa_ref *r = NULL;
- int i;
-
- for (i = 0; ipa_ref_list_reference_iterate (&referring_node->ref_list, i, r); i++)
- if (r->referred == referred_node
- && !r->speculative
- && ((stmt && r->stmt == stmt)
- || (lto_stmt_uid && r->lto_stmt_uid == lto_stmt_uid)
- || (!stmt && !lto_stmt_uid && !r->stmt && !r->lto_stmt_uid)))
- return r;
- return NULL;
+ return &referring->ref_list;
}
-/* Remove all references from REFERRING_NODE that are associated with statement
- STMT. */
+/* Return reference list this reference is in. */
-void
-ipa_remove_stmt_references (symtab_node *referring_node, gimple stmt)
+struct ipa_ref_list *
+ipa_ref::referred_ref_list (void)
{
- struct ipa_ref *r = NULL;
- int i = 0;
-
- while (ipa_ref_list_reference_iterate (&referring_node->ref_list, i, r))
- if (r->stmt == stmt)
- ipa_remove_reference (r);
- else
- i++;
-}
-
-/* Remove all stmt references in non-speculative references.
- Those are not maintained during inlining & clonning.
- The exception are speculative references that are updated along
- with callgraph edges associated with them. */
-
-void
-ipa_clear_stmts_in_references (symtab_node *referring_node)
-{
- struct ipa_ref *r = NULL;
- int i;
-
- for (i = 0; ipa_ref_list_reference_iterate (&referring_node->ref_list, i, r); i++)
- if (!r->speculative)
- {
- r->stmt = NULL;
- r->lto_stmt_uid = 0;
- }
+ return &referred->ref_list;
}
diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h
index 4ce5f8d..d2de006 100644
--- a/gcc/ipa-ref.h
+++ b/gcc/ipa-ref.h
@@ -35,6 +35,20 @@ enum GTY(()) ipa_ref_use
/* Record of reference in callgraph or varpool. */
struct GTY(()) ipa_ref
{
+public:
+ /* Remove reference. */
+ void remove_reference ();
+
+ /* Return true when execution of reference can lead to return from
+ function. */
+ bool cannot_lead_to_return ();
+
+ /* Return reference list this reference is in. */
+ struct ipa_ref_list * referring_ref_list (void);
+
+ /* Return reference list this reference is in. */
+ struct ipa_ref_list * referred_ref_list (void);
+
symtab_node *referring;
symtab_node *referred;
gimple stmt;
@@ -51,29 +65,39 @@ typedef struct ipa_ref *ipa_ref_ptr;
/* List of references. This is stored in both callgraph and varpool nodes. */
struct GTY(()) ipa_ref_list
{
+public:
+ /* Return first reference in list or NULL if empty. */
+ struct ipa_ref *first_reference (void)
+ {
+ if (!vec_safe_length (references))
+ return NULL;
+ return &(*references)[0];
+ }
+
+ /* Return first referring ref in list or NULL if empty. */
+ struct ipa_ref *first_referring (void)
+ {
+ if (!referring.length ())
+ return NULL;
+ return referring[0];
+ }
+
+ /* Clear reference list. */
+ void clear (void)
+ {
+ referring.create (0);
+ references = NULL;
+ }
+
+ /* Return number of references. */
+ unsigned int nreferences (void)
+ {
+ return vec_safe_length (references);
+ }
+
/* Store actual references in references vector. */
vec<ipa_ref_t, va_gc> *references;
/* Referring is vector of pointers to references. It must not live in GGC space
or GGC will try to mark middle of references vectors. */
vec<ipa_ref_ptr> GTY((skip)) referring;
};
-
-struct ipa_ref * ipa_record_reference (symtab_node *,
- symtab_node *,
- enum ipa_ref_use, gimple);
-struct ipa_ref * ipa_maybe_record_reference (symtab_node *, tree,
- enum ipa_ref_use, gimple);
-
-void ipa_remove_reference (struct ipa_ref *);
-void ipa_remove_all_references (struct ipa_ref_list *);
-void ipa_remove_all_referring (struct ipa_ref_list *);
-void ipa_dump_references (FILE *, struct ipa_ref_list *);
-void ipa_dump_referring (FILE *, struct ipa_ref_list *);
-void ipa_clone_references (symtab_node *, struct ipa_ref_list *);
-void ipa_clone_referring (symtab_node *, struct ipa_ref_list *);
-struct ipa_ref * ipa_clone_ref (struct ipa_ref *, symtab_node *, gimple);
-bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
-bool ipa_ref_has_aliases_p (struct ipa_ref_list *);
-struct ipa_ref * ipa_find_reference (symtab_node *, symtab_node *, gimple, unsigned int);
-void ipa_remove_stmt_references (symtab_node *, gimple);
-void ipa_clear_stmts_in_references (symtab_node *);
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index e815454..064fde2 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -450,16 +450,16 @@ static void
analyze_function (struct cgraph_node *fn)
{
ipa_reference_local_vars_info_t local;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
int i;
tree var;
local = init_function_info (fn);
- for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
+ for (i = 0; fn->iterate_reference (i, ref); i++)
{
if (!is_a <varpool_node *> (ref->referred))
continue;
- var = ipa_ref_varpool_node (ref)->decl;
+ var = ref->referred->decl;
if (!is_proper_for_analysis (var))
continue;
switch (ref->use)
@@ -468,7 +468,7 @@ analyze_function (struct cgraph_node *fn)
bitmap_set_bit (local->statics_read, DECL_UID (var));
break;
case IPA_REF_STORE:
- if (ipa_ref_cannot_lead_to_return (ref))
+ if (ref->cannot_lead_to_return ())
break;
bitmap_set_bit (local->statics_written, DECL_UID (var));
break;
@@ -882,7 +882,7 @@ write_node_summary_p (struct cgraph_node *node,
In future we might also want to include summaries of functions references
by initializers of constant variables references in current unit. */
if (!reachable_from_this_partition_p (node, encoder)
- && !referenced_from_this_partition_p (&node->ref_list, encoder))
+ && !referenced_from_this_partition_p (node, encoder))
return false;
/* See if the info has non-empty intersections with vars we want to encode. */
@@ -949,7 +949,7 @@ ipa_reference_write_optimization_summary (void)
varpool_node *vnode = dyn_cast <varpool_node *> (snode);
if (vnode
&& bitmap_bit_p (all_module_statics, DECL_UID (vnode->decl))
- && referenced_from_this_partition_p (&vnode->ref_list, encoder))
+ && referenced_from_this_partition_p (vnode, encoder))
{
tree decl = vnode->decl;
bitmap_set_bit (ltrans_statics, DECL_UID (decl));
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index bfcd43e..3ca57b6 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1251,7 +1251,7 @@ split_function (struct split_point *split_point)
a warning for the non-inlinable part. */
DECL_NO_INLINE_WARNING_P (node->decl) = 1;
cgraph_node_remove_callees (cur_node);
- ipa_remove_all_references (&cur_node->ref_list);
+ cur_node->remove_all_references ();
if (!split_part_return_p)
TREE_THIS_VOLATILE (node->decl) = 1;
if (dump_file)
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 8e7c7cb..c191210 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -289,7 +289,7 @@ ipa_reverse_postorder (struct cgraph_node **order)
int order_pos = 0;
struct cgraph_edge *edge;
int pass;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
struct postorder_stack *stack =
XCNEWVEC (struct postorder_stack, cgraph_n_nodes);
@@ -332,13 +332,13 @@ ipa_reverse_postorder (struct cgraph_node **order)
(cgraph_function_node (edge->callee, NULL)->decl))
node2 = NULL;
}
- for (;ipa_ref_list_referring_iterate (&stack[stack_size].node->ref_list,
+ for (; stack[stack_size].node->iterate_referring (
stack[stack_size].ref,
ref) && !node2;
stack[stack_size].ref++)
{
if (ref->use == IPA_REF_ALIAS)
- node2 = ipa_ref_referring_node (ref);
+ node2 = dyn_cast <cgraph_node *> (ref->referring);
}
if (!node2)
break;
diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c
index 9e4d8c3..a4848c2 100644
--- a/gcc/ipa-visibility.c
+++ b/gcc/ipa-visibility.c
@@ -91,7 +91,7 @@ cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED
{
/* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
return !(cgraph_only_called_directly_or_aliased_p (node)
- && !ipa_ref_has_aliases_p (&node->ref_list)
+ && !node->has_aliases_p ()
&& node->definition
&& !DECL_EXTERNAL (node->decl)
&& !node->externally_visible
@@ -120,15 +120,15 @@ bool
address_taken_from_non_vtable_p (symtab_node *node)
{
int i;
- struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
- i, ref); i++)
+ struct ipa_ref *ref = NULL;
+
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ADDR)
{
varpool_node *node;
if (is_a <cgraph_node *> (ref->referring))
return true;
- node = ipa_ref_referring_varpool_node (ref);
+ node = dyn_cast <varpool_node *> (ref->referring);
if (!DECL_VIRTUAL_P (node->decl))
return true;
}
@@ -682,8 +682,7 @@ function_and_variable_visibility (bool whole_program)
bool found = false;
/* See if there is something to update. */
- for (i = 0; ipa_ref_list_referring_iterate (&vnode->ref_list,
- i, ref); i++)
+ for (i = 0; vnode->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ADDR
&& can_replace_by_local_alias_in_vtable (ref->referred))
{
@@ -696,7 +695,7 @@ function_and_variable_visibility (bool whole_program)
walk_tree (&DECL_INITIAL (vnode->decl),
update_vtable_references, NULL, visited_nodes);
pointer_set_destroy (visited_nodes);
- ipa_remove_all_references (&vnode->ref_list);
+ vnode->remove_all_references ();
record_references_in_initializer (vnode->decl, false);
}
}
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 04f2c79..fce2e36 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -51,10 +51,9 @@ has_addr_references_p (struct cgraph_node *node,
void *data ATTRIBUTE_UNUSED)
{
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
- i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ADDR)
return true;
return false;
@@ -101,14 +100,14 @@ enqueue_node (symtab_node *node, symtab_node **first,
/* Process references. */
static void
-process_references (struct ipa_ref_list *list,
+process_references (symtab_node *snode,
symtab_node **first,
bool before_inlining_p,
struct pointer_set_t *reachable)
{
int i;
- struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
+ struct ipa_ref *ref = NULL;
+ for (i = 0; snode->iterate_reference (i, ref); i++)
{
symtab_node *node = ref->referred;
@@ -358,8 +357,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
enqueue_node (next, &first, reachable);
}
/* Mark references as reachable. */
- process_references (&node->ref_list, &first,
- before_inlining_p, reachable);
+ process_references (node, &first, before_inlining_p, reachable);
}
if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
@@ -446,8 +444,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
&& !vnode->alias
&& in_boundary_p)
{
- struct ipa_ref *ref;
- for (int i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
+ struct ipa_ref *ref = NULL;
+ for (int i = 0; node->iterate_reference (i, ref); i++)
enqueue_node (ref->referred, &first, reachable);
}
}
@@ -493,7 +491,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
node->local.local = false;
cgraph_node_remove_callees (node);
symtab_remove_from_same_comdat_group (node);
- ipa_remove_all_references (&node->ref_list);
+ node->remove_all_references ();
changed = true;
}
}
@@ -555,7 +553,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
varpool_remove_initializer (vnode);
else
DECL_INITIAL (vnode->decl) = init;
- ipa_remove_all_references (&vnode->ref_list);
+ vnode->remove_all_references ();
}
else
vnode->aux = NULL;
@@ -618,8 +616,7 @@ process_references (varpool_node *vnode,
|| TREE_THIS_VOLATILE (vnode->decl))
*explicit_refs = false;
- for (i = 0; ipa_ref_list_referring_iterate (&vnode->ref_list,
- i, ref)
+ for (i = 0; vnode->iterate_referring (i, ref)
&& *explicit_refs && (!*written || !*address_taken || !*read); i++)
switch (ref->use)
{
@@ -658,7 +655,7 @@ set_writeonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
{
DECL_INITIAL (vnode->decl) = NULL;
if (!vnode->alias)
- ipa_remove_all_references (&vnode->ref_list);
+ vnode->remove_all_references ();
}
return false;
}
@@ -1153,7 +1150,7 @@ propagate_single_user (varpool_node *vnode, cgraph_node *function,
/* Check all users and see if they correspond to a single function. */
for (i = 0;
- ipa_ref_list_referring_iterate (&vnode->ref_list, i, ref)
+ vnode->iterate_referring (i, ref)
&& function != BOTTOM; i++)
{
struct cgraph_node *cnode = dyn_cast <cgraph_node *> (ref->referring);
@@ -1221,7 +1218,7 @@ ipa_single_use (void)
/* Enqueue all aliases for re-processing. */
for (i = 0;
- ipa_ref_list_referring_iterate (&var->ref_list, i, ref); i++)
+ var->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS
&& !ref->referring->aux)
{
@@ -1230,7 +1227,7 @@ ipa_single_use (void)
}
/* Enqueue all users for re-processing. */
for (i = 0;
- ipa_ref_list_reference_iterate (&var->ref_list, i, ref); i++)
+ var->iterate_reference (i, ref); i++)
if (!ref->referred->aux
&& ref->referred->definition
&& is_a <varpool_node *> (ref->referred))
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index ffc6247..af480bc 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -315,14 +315,15 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
}
}
-/* Return if LIST contain references from other partitions. */
+/* Return if NODE contain references from other partitions. */
bool
-referenced_from_other_partition_p (struct ipa_ref_list *list, lto_symtab_encoder_t encoder)
+referenced_from_other_partition_p (symtab_node *node, lto_symtab_encoder_t encoder)
{
int i;
- struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_referring_iterate (list, i, ref); i++)
+ struct ipa_ref *ref = NULL;
+
+ for (i = 0; node->iterate_referring (i, ref); i++)
{
if (ref->referring->in_other_partition
|| !lto_symtab_encoder_in_partition_p (encoder, ref->referring))
@@ -348,15 +349,16 @@ reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t
return false;
}
-/* Return if LIST contain references from other partitions. */
+/* Return if NODE contain references from other partitions. */
bool
-referenced_from_this_partition_p (struct ipa_ref_list *list,
+referenced_from_this_partition_p (symtab_node *node,
lto_symtab_encoder_t encoder)
{
int i;
- struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_referring_iterate (list, i, ref); i++)
+ struct ipa_ref *ref = NULL;
+
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (lto_symtab_encoder_in_partition_p (encoder, ref->referring))
return true;
return false;
@@ -523,8 +525,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bp_pack_value (&bp, tag == LTO_symtab_analyzed_node
&& symtab_get_symbol_partitioning_class (node) == SYMBOL_PARTITION
&& (reachable_from_other_partition_p (node, encoder)
- || referenced_from_other_partition_p (&node->ref_list,
- encoder)), 1);
+ || referenced_from_other_partition_p (node, encoder)), 1);
bp_pack_value (&bp, node->lowered, 1);
bp_pack_value (&bp, in_other_partition, 1);
/* Real aliases in a boundary become non-aliases. However we still stream
@@ -607,8 +608,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
else
{
bp_pack_value (&bp, node->definition
- && referenced_from_other_partition_p (&node->ref_list,
- encoder), 1);
+ && referenced_from_other_partition_p (node, encoder), 1);
bp_pack_value (&bp, node->analyzed
&& boundary_p && !DECL_EXTERNAL (node->decl), 1);
/* in_other_partition. */
@@ -760,14 +760,13 @@ output_refs (lto_symtab_encoder_t encoder)
{
symtab_node *node = lsei_node (lsei);
- count = ipa_ref_list_nreferences (&node->ref_list);
+ count = node->ref_list.nreferences ();
if (count)
{
streamer_write_gcov_count_stream (ob->main_stream, count);
streamer_write_uhwi_stream (ob->main_stream,
lto_symtab_encoder_lookup (encoder, node));
- for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list,
- i, ref); i++)
+ for (i = 0; node->iterate_reference (i, ref); i++)
lto_output_ref (ob, ref, encoder);
}
}
@@ -791,17 +790,16 @@ add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
lto_symtab_encoder_encode (encoder, node);
}
-/* Add all references in LIST to encoders. */
+/* Add all references in NODE to encoders. */
static void
-add_references (lto_symtab_encoder_t encoder,
- struct ipa_ref_list *list)
+add_references (lto_symtab_encoder_t encoder, symtab_node *node)
{
int i;
- struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
+ struct ipa_ref *ref = NULL;
+ for (i = 0; node->iterate_reference (i, ref); i++)
if (is_a <cgraph_node *> (ref->referred))
- add_node_to (encoder, ipa_ref_node (ref), false);
+ add_node_to (encoder, dyn_cast <cgraph_node *> (ref->referred), false);
else
lto_symtab_encoder_encode (encoder, ref->referred);
}
@@ -834,7 +832,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
struct cgraph_node *node = lsei_cgraph_node (lsei);
add_node_to (encoder, node, true);
lto_set_symtab_encoder_in_partition (encoder, node);
- add_references (encoder, &node->ref_list);
+ add_references (encoder, node);
/* For proper debug info, we need to ship the origins, too. */
if (DECL_ABSTRACT_ORIGIN (node->decl))
{
@@ -850,7 +848,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
lto_set_symtab_encoder_in_partition (encoder, vnode);
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
- add_references (encoder, &vnode->ref_list);
+ add_references (encoder, vnode);
/* For proper debug info, we need to ship the origins, too. */
if (DECL_ABSTRACT_ORIGIN (vnode->decl))
{
@@ -872,7 +870,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
&& ctor_for_folding (vnode->decl) != error_mark_node)
{
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
- add_references (encoder, &vnode->ref_list);
+ add_references (encoder, vnode);
}
}
}
@@ -1317,7 +1315,7 @@ input_ref (struct lto_input_block *ib,
use = (enum ipa_ref_use) bp_unpack_value (&bp, 2);
speculative = (enum ipa_ref_use) bp_unpack_value (&bp, 1);
node = nodes[streamer_read_hwi (ib)];
- ref = ipa_record_reference (referring_node, node, use, NULL);
+ ref = referring_node->add_reference (node, use);
ref->speculative = speculative;
if (is_a <cgraph_node *> (referring_node))
ref->lto_stmt_uid = streamer_read_hwi (ib);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 6715327..5d79893 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -785,7 +785,7 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts,
struct function *fn)
{
struct cgraph_edge *cedge;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
unsigned int i;
for (cedge = node->callees; cedge; cedge = cedge->next_callee)
@@ -804,9 +804,7 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts,
if (!cedge->call_stmt)
fatal_error ("Cgraph edge statement index not found");
}
- for (i = 0;
- ipa_ref_list_reference_iterate (&node->ref_list, i, ref);
- i++)
+ for (i = 0; node->iterate_reference (i, ref); i++)
if (ref->lto_stmt_uid)
{
if (gimple_stmt_max_uid (fn) < ref->lto_stmt_uid)
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index cb47b00..3064562 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -2362,8 +2362,7 @@ output_symbol_p (symtab_node *node)
{
int i;
struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
- i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
{
if (ref->use == IPA_REF_ALIAS)
continue;
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 566a0e0..cfa965c 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -888,7 +888,7 @@ bool referenced_from_other_partition_p (struct ipa_ref_list *,
lto_symtab_encoder_t);
bool reachable_from_other_partition_p (struct cgraph_node *,
lto_symtab_encoder_t);
-bool referenced_from_this_partition_p (struct ipa_ref_list *,
+bool referenced_from_this_partition_p (struct symtab_node *,
lto_symtab_encoder_t);
bool reachable_from_this_partition_p (struct cgraph_node *,
lto_symtab_encoder_t);
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 5a8c843..4d19ef6 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -86,10 +86,10 @@ static void
add_references_to_partition (ltrans_partition part, symtab_node *node)
{
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
/* Add all duplicated references to the partition. */
- for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_reference (i, ref); i++)
if (symtab_get_symbol_partitioning_class (ref->referred) == SYMBOL_DUPLICATE)
add_symbol_to_partition (part, ref->referred);
/* References to a readonly variable may be constant foled into its value.
@@ -114,7 +114,7 @@ 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;
+ struct ipa_ref *ref = NULL;
symtab_node *node1;
/* If NODE is already there, we have nothing to do. */
@@ -168,7 +168,7 @@ 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; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS && !node->weakref)
add_symbol_to_partition_1 (part, ref->referring);
@@ -516,9 +516,9 @@ lto_balanced_map (int n_lto_partitions)
it and thus we need to subtract it from COST. */
while (last_visited_node < lto_symtab_encoder_size (partition->encoder))
{
- struct ipa_ref_list *refs;
+ symtab_node *refs_node;
int j;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
symtab_node *snode = lto_symtab_encoder_deref (partition->encoder,
last_visited_node);
@@ -526,7 +526,7 @@ lto_balanced_map (int n_lto_partitions)
{
struct cgraph_edge *edge;
- refs = &node->ref_list;
+ refs_node = node;
last_visited_node++;
@@ -570,18 +570,18 @@ lto_balanced_map (int n_lto_partitions)
}
else
{
- refs = &snode->ref_list;
+ refs_node = snode;
last_visited_node++;
}
/* Compute boundary cost of IPA REF edges and at the same time look into
variables referenced from current partition and try to add them. */
- for (j = 0; ipa_ref_list_reference_iterate (refs, j, ref); j++)
+ for (j = 0; refs_node->iterate_reference (j, ref); j++)
if (is_a <varpool_node *> (ref->referred))
{
int index;
- vnode = ipa_ref_varpool_node (ref);
+ vnode = dyn_cast <varpool_node *> (ref->referred);
if (!vnode->definition)
continue;
if (!symbol_partitioned_p (vnode) && flag_toplevel_reorder
@@ -599,7 +599,7 @@ lto_balanced_map (int n_lto_partitions)
{
int index;
- node = ipa_ref_node (ref);
+ node = dyn_cast <cgraph_node *> (ref->referred);
if (!node->definition)
continue;
index = lto_symtab_encoder_lookup (partition->encoder,
@@ -610,12 +610,12 @@ lto_balanced_map (int n_lto_partitions)
else
cost++;
}
- for (j = 0; ipa_ref_list_referring_iterate (refs, j, ref); j++)
+ for (j = 0; refs_node->iterate_referring (j, ref); j++)
if (is_a <varpool_node *> (ref->referring))
{
int index;
- vnode = ipa_ref_referring_varpool_node (ref);
+ vnode = dyn_cast <varpool_node *> (ref->referring);
gcc_assert (vnode->definition);
/* It is better to couple variables with their users, because it allows them
to be removed. Coupling with objects they refer to only helps to reduce
@@ -636,7 +636,7 @@ lto_balanced_map (int n_lto_partitions)
{
int index;
- node = ipa_ref_referring_node (ref);
+ node = dyn_cast <cgraph_node *> (ref->referring);
gcc_assert (node->definition);
index = lto_symtab_encoder_lookup (partition->encoder,
node);
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index c02f987..82ee827 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -84,7 +84,7 @@ lto_cgraph_replace_node (struct cgraph_node *node,
e->call_stmt_cannot_inline_p = 1;
}
/* Redirect incomming references. */
- ipa_clone_referring (prevailing_node, &node->ref_list);
+ prevailing_node->clone_referring (node);
ipa_merge_profiles (prevailing_node, node);
lto_free_function_in_decl_state_for_node (node);
@@ -106,7 +106,7 @@ lto_varpool_replace_node (varpool_node *vnode,
gcc_assert (!vnode->definition || prevailing_node->definition);
gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
- ipa_clone_referring (prevailing_node, &vnode->ref_list);
+ prevailing_node->clone_referring (vnode);
if (vnode->force_output)
prevailing_node->force_output = true;
if (vnode->forced_by_abi)
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 6e52115..89591ee 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -42,6 +42,9 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "lto-streamer.h"
#include "output.h"
+#include "ipa-utils.h"
+
+static const char *ipa_ref_use_name[] = {"read","write","addr","alias"};
const char * const ld_plugin_symbol_resolution_names[]=
{
@@ -284,7 +287,7 @@ symtab_register_node (symtab_node *node)
if (!node->decl->decl_with_vis.symtab_node)
node->decl->decl_with_vis.symtab_node = node;
- ipa_empty_ref_list (&node->ref_list);
+ node->ref_list.clear ();
node->order = symtab_order++;
@@ -319,8 +322,8 @@ symtab_remove_from_same_comdat_group (symtab_node *node)
void
symtab_unregister_node (symtab_node *node)
{
- ipa_remove_all_references (&node->ref_list);
- ipa_remove_all_referring (&node->ref_list);
+ node->remove_all_references ();
+ node->remove_all_referring ();
/* Remove reference to section. */
node->set_section_for_node (NULL);
@@ -522,6 +525,277 @@ symtab_node::name () const
return lang_hooks.decl_printable_name (decl, 2);
}
+/* Return ipa reference from this symtab_node to
+ REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
+ of the use. */
+
+struct ipa_ref *
+symtab_node::add_reference (symtab_node *referred_node,
+ enum ipa_ref_use use_type)
+{
+ return add_reference (referred_node, use_type, NULL);
+}
+
+
+/* Return ipa reference from this symtab_node to
+ REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
+ of the use and STMT the statement (if it exists). */
+
+struct ipa_ref *
+symtab_node::add_reference (symtab_node *referred_node,
+ enum ipa_ref_use use_type, gimple stmt)
+{
+ struct ipa_ref *ref = NULL, *ref2 = NULL;
+ struct ipa_ref_list *list, *list2;
+ ipa_ref_t *old_references;
+
+ gcc_checking_assert (!stmt || is_a <cgraph_node *> (this));
+ gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt);
+
+ list = &ref_list;
+ old_references = vec_safe_address (list->references);
+ vec_safe_grow (list->references, vec_safe_length (list->references) + 1);
+ ref = &list->references->last ();
+
+ list2 = &referred_node->ref_list;
+ list2->referring.safe_push (ref);
+ ref->referred_index = list2->referring.length () - 1;
+ ref->referring = this;
+ ref->referred = referred_node;
+ ref->stmt = stmt;
+ ref->lto_stmt_uid = 0;
+ ref->use = use_type;
+ ref->speculative = 0;
+
+ /* If vector was moved in memory, update pointers. */
+ if (old_references != list->references->address ())
+ {
+ int i;
+ for (i = 0; iterate_reference(i, ref2); i++)
+ ref2->referred_ref_list ()->referring[ref2->referred_index] = ref2;
+ }
+ return ref;
+}
+
+/* If VAL is a reference to a function or a variable, add a reference from
+ this symtab_node to the corresponding symbol table node. USE_TYPE specify
+ type of the use and STMT the statement (if it exists). Return the new
+ reference or NULL if none was created. */
+
+struct ipa_ref *
+symtab_node::maybe_add_reference (tree val, enum ipa_ref_use use_type,
+ gimple stmt)
+{
+ STRIP_NOPS (val);
+ if (TREE_CODE (val) != ADDR_EXPR)
+ return NULL;
+ val = get_base_var (val);
+ if (val && (TREE_CODE (val) == FUNCTION_DECL
+ || TREE_CODE (val) == VAR_DECL))
+ {
+ symtab_node *referred = symtab_get_node (val);
+ gcc_checking_assert (referred);
+ return add_reference (referred, use_type, stmt);
+ }
+ return NULL;
+}
+
+/* Clone all references from symtab NODE to this symtab_node. */
+
+void
+symtab_node::clone_references (struct symtab_node *node)
+{
+ struct ipa_ref *ref = NULL, *ref2 = NULL;
+ int i;
+ for (i = 0; node->iterate_reference (i, ref); i++)
+ {
+ bool speculative = ref->speculative;
+ unsigned int stmt_uid = ref->lto_stmt_uid;
+
+ ref2 = add_reference (ref->referred, ref->use, ref->stmt);
+ ref2->speculative = speculative;
+ ref2->lto_stmt_uid = stmt_uid;
+ }
+}
+
+/* Clone all referring from symtab NODE to this symtab_node. */
+
+void
+symtab_node::clone_referring (struct symtab_node *node)
+{
+ struct ipa_ref *ref = NULL, *ref2 = NULL;
+ int i;
+ for (i = 0; node->iterate_referring(i, ref); i++)
+ {
+ bool speculative = ref->speculative;
+ unsigned int stmt_uid = ref->lto_stmt_uid;
+
+ ref2 = ref->referring->add_reference (this, ref->use, ref->stmt);
+ ref2->speculative = speculative;
+ ref2->lto_stmt_uid = stmt_uid;
+ }
+}
+
+/* Clone reference REF to this symtab_node and set its stmt to STMT. */
+
+struct ipa_ref *
+symtab_node::clone_reference (struct ipa_ref *ref, gimple stmt)
+{
+ bool speculative = ref->speculative;
+ unsigned int stmt_uid = ref->lto_stmt_uid;
+ struct ipa_ref *ref2;
+
+ ref2 = add_reference (ref->referred, ref->use, stmt);
+ ref2->speculative = speculative;
+ ref2->lto_stmt_uid = stmt_uid;
+ return ref2;
+}
+
+/* Find the structure describing a reference to REFERRED_NODE
+ and associated with statement STMT. */
+
+struct ipa_ref *
+symtab_node::find_reference (symtab_node *referred_node,
+ gimple stmt, unsigned int lto_stmt_uid)
+{
+ struct ipa_ref *r = NULL;
+ int i;
+
+ for (i = 0; iterate_reference (i, r); i++)
+ if (r->referred == referred_node
+ && !r->speculative
+ && ((stmt && r->stmt == stmt)
+ || (lto_stmt_uid && r->lto_stmt_uid == lto_stmt_uid)
+ || (!stmt && !lto_stmt_uid && !r->stmt && !r->lto_stmt_uid)))
+ return r;
+ return NULL;
+}
+
+/* Remove all references that are associated with statement STMT. */
+
+void
+symtab_node::remove_stmt_references (gimple stmt)
+{
+ struct ipa_ref *r = NULL;
+ int i = 0;
+
+ while (iterate_reference (i, r))
+ if (r->stmt == stmt)
+ r->remove_reference ();
+ else
+ i++;
+}
+
+/* Remove all stmt references in non-speculative references.
+ Those are not maintained during inlining & clonning.
+ The exception are speculative references that are updated along
+ with callgraph edges associated with them. */
+
+void
+symtab_node::clear_stmts_in_references (void)
+{
+ struct ipa_ref *r = NULL;
+ int i;
+
+ for (i = 0; iterate_reference (i, r); i++)
+ if (!r->speculative)
+ {
+ r->stmt = NULL;
+ r->lto_stmt_uid = 0;
+ }
+}
+
+/* Remove all references in ref list. */
+
+void
+symtab_node::remove_all_references (void)
+{
+ while (vec_safe_length (ref_list.references))
+ ref_list.references->last ().remove_reference ();
+ vec_free (ref_list.references);
+}
+
+/* Remove all referring items in ref list. */
+
+void
+symtab_node::remove_all_referring (void)
+{
+ while (ref_list.referring.length ())
+ ref_list.referring.last ()->remove_reference ();
+ ref_list.referring.release ();
+}
+
+/* Dump references in ref list to FILE. */
+
+void
+symtab_node::dump_references (FILE *file)
+{
+ struct ipa_ref *ref = NULL;
+ int i;
+ for (i = 0; iterate_reference (i, ref); i++)
+ {
+ fprintf (file, "%s/%i (%s)",
+ ref->referred->asm_name (),
+ ref->referred->order,
+ ipa_ref_use_name [ref->use]);
+ if (ref->speculative)
+ fprintf (file, " (speculative)");
+ }
+ fprintf (file, "\n");
+}
+
+/* Dump referring in list to FILE. */
+
+void
+symtab_node::dump_referring (FILE *file)
+{
+ struct ipa_ref *ref = NULL;
+ int i;
+ for (i = 0; iterate_referring(i, ref); i++)
+ {
+ fprintf (file, "%s/%i (%s)",
+ ref->referring->asm_name (),
+ ref->referring->order,
+ ipa_ref_use_name [ref->use]);
+ if (ref->speculative)
+ fprintf (file, " (speculative)");
+ }
+ fprintf (file, "\n");
+}
+
+/* Return true if list contains an alias. */
+bool
+symtab_node::has_aliases_p (void)
+{
+ struct ipa_ref *ref = NULL;
+ int i;
+
+ for (i = 0; iterate_referring (i, ref); i++)
+ if (ref->use == IPA_REF_ALIAS)
+ return true;
+ return false;
+}
+
+/* Iterates I-th reference in the list, REF is also set. */
+
+struct ipa_ref *
+symtab_node::iterate_reference (unsigned i, struct ipa_ref *&ref)
+{
+ vec_safe_iterate (ref_list.references, i, &ref);
+
+ return ref;
+}
+
+/* Iterates I-th referring item in the list, REF is also set. */
+
+struct ipa_ref *
+symtab_node::iterate_referring (unsigned i, struct ipa_ref *&ref)
+{
+ ref_list.referring.iterate (i, &ref);
+
+ return ref;
+}
+
static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
/* Dump base fields of symtab nodes. Not to be used directly. */
@@ -634,9 +908,9 @@ dump_symtab_base (FILE *f, symtab_node *node)
}
fprintf (f, " References: ");
- ipa_dump_references (f, &node->ref_list);
+ node->dump_references (f);
fprintf (f, " Referring: ");
- ipa_dump_referring (f, &node->ref_list);
+ node->dump_referring (f);
if (node->lto_file_data)
fprintf (f, " Read from file: %s\n",
node->lto_file_data->file_name);
@@ -819,10 +1093,9 @@ verify_symtab_base (symtab_node *node)
while (n != node);
if (symtab_comdat_local_p (node))
{
- struct ipa_ref_list *refs = &node->ref_list;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
- for (int i = 0; ipa_ref_list_referring_iterate (refs, i, ref); ++i)
+ for (int i = 0; node->iterate_referring (i, ref); ++i)
{
if (!symtab_in_same_comdat_p (ref->referring, node))
{
@@ -1355,7 +1628,7 @@ symtab_resolve_alias (symtab_node *node, symtab_node *target)
node->definition = true;
node->alias = true;
node->analyzed = true;
- ipa_record_reference (node, target, IPA_REF_ALIAS, NULL);
+ node->add_reference (target, IPA_REF_ALIAS, NULL);
/* Add alias into the comdat group of its target unless it is already there. */
if (node->same_comdat_group)
@@ -1406,7 +1679,7 @@ symtab_for_node_and_aliases (symtab_node *node,
if (callback (node, data))
return true;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
symtab_node *alias = ref->referring;
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index c4baa43..af8bc09 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -4860,7 +4860,7 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
record_tm_clone_pair (old_decl, new_decl);
if (info->old_node->force_output
- || ipa_ref_list_first_referring (&info->old_node->ref_list))
+ || info->old_node->ref_list.first_referring ())
ipa_tm_mark_force_output_node (new_node);
if (info->old_node->forced_by_abi)
ipa_tm_mark_forced_by_abi_node (new_node);
@@ -4919,7 +4919,7 @@ ipa_tm_create_version (struct cgraph_node *old_node)
cgraph_call_function_insertion_hooks (new_node);
if (old_node->force_output
- || ipa_ref_list_first_referring (&old_node->ref_list))
+ || old_node->ref_list.first_referring ())
ipa_tm_mark_force_output_node (new_node);
if (old_node->forced_by_abi)
ipa_tm_mark_forced_by_abi_node (new_node);
@@ -5439,7 +5439,7 @@ ipa_tm_execute (void)
{
struct cgraph_node *caller;
struct cgraph_edge *e;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
unsigned j;
if (i > 256 && i == irr_worklist.length () / 8)
@@ -5466,7 +5466,7 @@ ipa_tm_execute (void)
}
/* Propagate back to referring aliases as well. */
- for (j = 0; ipa_ref_list_referring_iterate (&node->ref_list, j, ref); j++)
+ for (j = 0; node->iterate_referring (j, ref); j++)
{
caller = cgraph (ref->referring);
if (ref->use == IPA_REF_ALIAS
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index fe1e85d..3a486305 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -453,7 +453,7 @@ gen_emutls_addr (tree decl, struct lower_emutls_data *d)
/* We may be adding a new reference to a new variable to the function.
This means we have to play with the ipa-reference web. */
- ipa_record_reference (d->cfun_node, cvar, IPA_REF_ADDR, x);
+ d->cfun_node->add_reference (cvar, IPA_REF_ADDR, x);
/* Record this ssa_name for possible use later in the basic block. */
access_vars[index] = addr;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6b4d3f3..f07c1a8 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1791,7 +1791,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
(old_edge->frequency + indirect->frequency)),
CGRAPH_FREQ_MAX);
}
- ipa_clone_ref (ref, id->dst_node, stmt);
+ id->dst_node->clone_reference (ref, stmt);
}
else
{
@@ -5169,7 +5169,7 @@ delete_unreachable_blocks_update_callgraph (copy_body_data *id)
struct cgraph_edge *e;
struct cgraph_node *node;
- ipa_remove_stmt_references (id->dst_node, gsi_stmt (bsi));
+ id->dst_node->remove_stmt_references (gsi_stmt (bsi));
if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL
&&(e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL)
@@ -5183,7 +5183,7 @@ delete_unreachable_blocks_update_callgraph (copy_body_data *id)
&& id->dst_node->clones)
for (node = id->dst_node->clones; node != id->dst_node;)
{
- ipa_remove_stmt_references (node, gsi_stmt (bsi));
+ node->remove_stmt_references (gsi_stmt (bsi));
if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL
&& (e = cgraph_edge (node, gsi_stmt (bsi))) != NULL)
{
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 580144e..04ac870 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -425,11 +425,12 @@ static void
assemble_aliases (varpool_node *node)
{
int i;
- struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
+ struct ipa_ref *ref = NULL;
+
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
- varpool_node *alias = ipa_ref_referring_varpool_node (ref);
+ varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
do_assemble_alias (alias->decl,
DECL_ASSEMBLER_NAME (node->decl));
assemble_aliases (alias);
@@ -506,7 +507,7 @@ varpool_remove_unreferenced_decls (void)
varpool_node *next, *node;
varpool_node *first = (varpool_node *)(void *)1;
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
struct pointer_set_t *referenced = pointer_set_create ();
if (seen_error ())
@@ -544,7 +545,7 @@ varpool_remove_unreferenced_decls (void)
enqueue_node (vnext, &first);
}
}
- for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_reference (i, ref); i++)
{
varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
if (vnode
@@ -694,14 +695,14 @@ varpool_for_node_and_aliases (varpool_node *node,
bool include_overwritable)
{
int i;
- struct ipa_ref *ref;
+ struct ipa_ref *ref = NULL;
if (callback (node, data))
return true;
- for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
+ for (i = 0; node->iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
- varpool_node *alias = ipa_ref_referring_varpool_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,