aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorLawrence Crowl <crowl@google.com>2012-10-31 23:15:10 +0000
committerLawrence Crowl <crowl@google.com>2012-10-31 23:15:10 +0000
commit52f6d74952fe52b93ada42de96adbdf739d39d25 (patch)
tree7209857044c64b9be2543946aeb701d483464efa /gcc/ipa.c
parentcffbd58647d3f5c86f84e301b1a0291b52d1f933 (diff)
This patch implements generic type query and conversion functions,
and applies them to the use of cgraph_node, varpool_node, and symtab_node. The functions are: bool is_a <TYPE> (pointer) Tests whether the pointer actually points to a more derived TYPE. TYPE *as_a <TYPE> (pointer) Converts pointer to a TYPE*. TYPE *dyn_cast <TYPE> (pointer) Converts pointer to TYPE* if and only if "is_a <TYPE> pointer". Otherwise, returns NULL. This function is essentially a checked down cast. These functions reduce compile time and increase type safety when treating a generic item as a more specific item. In essence, the code change is from if (symtab_function_p (node)) { struct cgraph_node *cnode = cgraph (node); .... } to if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) { .... } The necessary conditional test defines a variable that holds a known good pointer to the specific item and avoids subsequent conversion calls and the assertion checks that may come with them. When, the property test is embedded within a larger condition, the variable declaration gets pulled out of the condition. (This leaves some room for using the variable inappropriately.) if (symtab_variable_p (node) && varpool (node)->finalized) varpool_analyze_node (varpool (node)); becomes varpool_node *vnode = dyn_cast <varpool_node> (node); if (vnode && vnode->finalized) varpool_analyze_node (vnode); Note that we have converted two sets of assertions in the calls to varpool into safe and efficient use of a variable. There are remaining calls to symtab_function_p and symtab_variable_p that do not involve a pointer to a more specific type. These have been converted to calls to a functions is_a <cgraph_node> and is_a <varpool_node>. The original predicate functions have been removed. The cgraph.h header defined both a struct and a function with the name varpool_node. This name overloading can cause some unintuitive error messages when, as is common in C++, one omits the struct keyword when using the type. I have renamed the function to varpool_node_for_decl. Tested on x86_64. Index: gcc/ChangeLog 2012-10-31 Lawrence Crowl <crowl@google.com> * is-a.h: New. (is_a <T> (U*)): New. Test for is-a relationship. (as_a <T> (U*)): New. Treat as a derived type. (dyn_cast <T> (U*)): New. Conditionally cast based on is_a. * cgraph.h (varpool_node): Rename to varpool_node_for_decl. Adjust callers to match. (is_a_helper <cgraph_node>::test (symtab_node_def *)): New. (is_a_helper <varpool_node>::test (symtab_node_def *)): New. (symtab_node_def::try_function): New. Change most calls to symtab_function_p with calls to dyn_cast <cgraph_node> (p). (symtab_node_def::try_variable): New. Change most calls to symtab_variable_p with calls to dyn_cast <varpool_node> (p). (symtab_function_p): Remove. Change callers to use is_a <cgraph_node> (p) instead. (symtab_variable_p): Remove. Change callers to use is_a <varpool_node> (p) instead. * cgraph.c (cgraph_node_for_asm): Remove redundant call to symtab_node_for_asm. * cgraphunit.c (symbol_finalized_and_needed): New. (symbol_finalized): New. (cgraph_analyze_functions): Split complicated conditionals out into above new functions. * Makefile.in (CGRAPH_H): Add is-a.h as used by cgraph.h. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@193051 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r--gcc/ipa.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/gcc/ipa.c b/gcc/ipa.c
index e2705918077..e5737f4d027 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -84,7 +84,7 @@ process_references (struct ipa_ref_list *list,
struct ipa_ref *ref;
for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
{
- if (symtab_function_p (ref->referred))
+ if (is_a <cgraph_node> (ref->referred))
{
struct cgraph_node *node = ipa_ref_node (ref);
@@ -290,10 +290,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
before_inlining_p, reachable);
}
- if (symtab_function_p (node))
+ if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
{
- struct cgraph_node *cnode = cgraph (node);
-
/* Mark the callees reachable unless they are direct calls to extern
inline functions we decided to not inline. */
if (!in_boundary_p)
@@ -332,18 +330,18 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
}
}
/* When we see constructor of external variable, keep referred nodes in the
- boundary. This will also hold initializers of the external vars NODE
- reffers to. */
- if (symtab_variable_p (node)
+ boundary. This will also hold initializers of the external vars NODE
+ refers to. */
+ varpool_node *vnode = dyn_cast <varpool_node> (node);
+ if (vnode
&& DECL_EXTERNAL (node->symbol.decl)
- && !varpool (node)->alias
+ && !vnode->alias
&& in_boundary_p)
- {
- int i;
+ {
struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
+ for (int i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
enqueue_node (ref->referred, &first, reachable);
- }
+ }
}
/* Remove unreachable functions. */
@@ -526,7 +524,7 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
if (ref->use == IPA_REF_ADDR)
{
struct varpool_node *node;
- if (symtab_function_p (ref->referring))
+ if (is_a <cgraph_node> (ref->referring))
return true;
node = ipa_ref_referring_varpool_node (ref);
if (!DECL_VIRTUAL_P (node->symbol.decl))