diff options
author | crowl <crowl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-31 23:15:10 +0000 |
---|---|---|
committer | crowl <crowl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-31 23:15:10 +0000 |
commit | 2dc9831fc1c17840efc629788027aeededa44d2f (patch) | |
tree | 7209857044c64b9be2543946aeb701d483464efa /gcc/cgraph.h | |
parent | e98dcfc2367b0800142ab02aaee07d1407ff51a3 (diff) | |
download | gcc-2dc9831fc1c17840efc629788027aeededa44d2f.tar.gz |
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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193051 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraph.h')
-rw-r--r-- | gcc/cgraph.h | 114 |
1 files changed, 59 insertions, 55 deletions
diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 6291f337aae..f276512df31 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_CGRAPH_H #define GCC_CGRAPH_H +#include "is-a.h" #include "plugin-api.h" #include "vec.h" #include "tree.h" @@ -457,12 +458,32 @@ struct GTY(()) asm_node { union GTY((desc ("%h.symbol.type"), chain_next ("%h.symbol.next"), chain_prev ("%h.symbol.previous"))) symtab_node_def { struct symtab_node_base GTY ((tag ("SYMTAB_SYMBOL"))) symbol; - /* Use cgraph (symbol) accessor to get cgraph_node. */ + /* To access the following fields, + use the use dyn_cast or as_a to obtain the concrete type. */ struct cgraph_node GTY ((tag ("SYMTAB_FUNCTION"))) x_function; - /* Use varpool (symbol) accessor to get varpool_node. */ struct varpool_node GTY ((tag ("SYMTAB_VARIABLE"))) x_variable; }; +/* Report whether or not THIS symtab node is a function, aka cgraph_node. */ + +template <> +template <> +inline bool +is_a_helper <cgraph_node>::test (symtab_node_def *p) +{ + return p->symbol.type == SYMTAB_FUNCTION; +} + +/* Report whether or not THIS symtab node is a vriable, aka varpool_node. */ + +template <> +template <> +inline bool +is_a_helper <varpool_node>::test (symtab_node_def *p) +{ + return p->symbol.type == SYMTAB_VARIABLE; +} + extern GTY(()) symtab_node symtab_nodes; extern GTY(()) int cgraph_n_nodes; extern GTY(()) int cgraph_max_uid; @@ -685,7 +706,7 @@ bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e); bool cgraph_optimize_for_size_p (struct cgraph_node *); /* In varpool.c */ -struct varpool_node *varpool_node (tree); +struct varpool_node *varpool_node_for_decl (tree); struct varpool_node *varpool_node_for_asm (tree asmname); void varpool_mark_needed_node (struct varpool_node *); void debug_varpool (void); @@ -715,19 +736,6 @@ void varpool_add_new_variable (tree); void symtab_initialize_asm_name_hash (void); void symtab_prevail_in_asm_name_hash (symtab_node node); -/* Return true when NODE is function. */ -static inline bool -symtab_function_p (symtab_node node) -{ - return node->symbol.type == SYMTAB_FUNCTION; -} - -/* Return true when NODE is variable. */ -static inline bool -symtab_variable_p (symtab_node node) -{ - return node->symbol.type == SYMTAB_VARIABLE; -} /* Return callgraph node for given symbol and check it is a function. */ static inline struct cgraph_node * @@ -800,10 +808,8 @@ varpool_first_variable (void) { symtab_node node; for (node = symtab_nodes; node; node = node->symbol.next) - { - if (symtab_variable_p (node)) - return varpool (node); - } + if (varpool_node *vnode = dyn_cast <varpool_node> (node)) + return vnode; return NULL; } @@ -813,10 +819,8 @@ varpool_next_variable (struct varpool_node *node) { symtab_node node1 = (symtab_node) node->symbol.next; for (; node1; node1 = node1->symbol.next) - { - if (symtab_variable_p (node1)) - return varpool (node1); - } + if (varpool_node *vnode1 = dyn_cast <varpool_node> (node1)) + return vnode1; return NULL; } /* Walk all variables. */ @@ -832,9 +836,9 @@ varpool_first_static_initializer (void) symtab_node node; for (node = symtab_nodes; node; node = node->symbol.next) { - if (symtab_variable_p (node) - && DECL_INITIAL (node->symbol.decl)) - return varpool (node); + varpool_node *vnode = dyn_cast <varpool_node> (node); + if (vnode && DECL_INITIAL (node->symbol.decl)) + return vnode; } return NULL; } @@ -846,9 +850,9 @@ varpool_next_static_initializer (struct varpool_node *node) symtab_node node1 = (symtab_node) node->symbol.next; for (; node1; node1 = node1->symbol.next) { - if (symtab_variable_p (node1) - && DECL_INITIAL (node1->symbol.decl)) - return varpool (node1); + varpool_node *vnode1 = dyn_cast <varpool_node> (node1); + if (vnode1 && DECL_INITIAL (node1->symbol.decl)) + return vnode1; } return NULL; } @@ -865,8 +869,9 @@ varpool_first_defined_variable (void) symtab_node node; for (node = symtab_nodes; node; node = node->symbol.next) { - if (symtab_variable_p (node) && varpool (node)->analyzed) - return varpool (node); + varpool_node *vnode = dyn_cast <varpool_node> (node); + if (vnode && vnode->analyzed) + return vnode; } return NULL; } @@ -878,8 +883,9 @@ varpool_next_defined_variable (struct varpool_node *node) symtab_node node1 = (symtab_node) node->symbol.next; for (; node1; node1 = node1->symbol.next) { - if (symtab_variable_p (node1) && varpool (node1)->analyzed) - return varpool (node1); + varpool_node *vnode1 = dyn_cast <varpool_node> (node1); + if (vnode1 && vnode1->analyzed) + return vnode1; } return NULL; } @@ -895,8 +901,9 @@ cgraph_first_defined_function (void) symtab_node node; for (node = symtab_nodes; node; node = node->symbol.next) { - if (symtab_function_p (node) && cgraph (node)->analyzed) - return cgraph (node); + cgraph_node *cn = dyn_cast <cgraph_node> (node); + if (cn && cn->analyzed) + return cn; } return NULL; } @@ -908,8 +915,9 @@ cgraph_next_defined_function (struct cgraph_node *node) symtab_node node1 = (symtab_node) node->symbol.next; for (; node1; node1 = node1->symbol.next) { - if (symtab_function_p (node1) && cgraph (node1)->analyzed) - return cgraph (node1); + cgraph_node *cn1 = dyn_cast <cgraph_node> (node1); + if (cn1 && cn1->analyzed) + return cn1; } return NULL; } @@ -925,10 +933,8 @@ cgraph_first_function (void) { symtab_node node; for (node = symtab_nodes; node; node = node->symbol.next) - { - if (symtab_function_p (node)) - return cgraph (node); - } + if (cgraph_node *cn = dyn_cast <cgraph_node> (node)) + return cn; return NULL; } @@ -938,10 +944,8 @@ cgraph_next_function (struct cgraph_node *node) { symtab_node node1 = (symtab_node) node->symbol.next; for (; node1; node1 = node1->symbol.next) - { - if (symtab_function_p (node1)) - return cgraph (node1); - } + if (cgraph_node *cn1 = dyn_cast <cgraph_node> (node1)) + return cn1; return NULL; } /* Walk all functions. */ @@ -968,9 +972,9 @@ cgraph_first_function_with_gimple_body (void) symtab_node node; for (node = symtab_nodes; node; node = node->symbol.next) { - if (symtab_function_p (node) - && cgraph_function_with_gimple_body_p (cgraph (node))) - return cgraph (node); + cgraph_node *cn = dyn_cast <cgraph_node> (node); + if (cn && cgraph_function_with_gimple_body_p (cn)) + return cn; } return NULL; } @@ -982,9 +986,9 @@ cgraph_next_function_with_gimple_body (struct cgraph_node *node) symtab_node node1 = node->symbol.next; for (; node1; node1 = node1->symbol.next) { - if (symtab_function_p (node1) - && cgraph_function_with_gimple_body_p (cgraph (node1))) - return cgraph (node1); + cgraph_node *cn1 = dyn_cast <cgraph_node> (node1); + if (cn1 && cgraph_function_with_gimple_body_p (cn1)) + return cn1; } return NULL; } @@ -1183,7 +1187,7 @@ cgraph_alias_aliased_node (struct cgraph_node *n) ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref); gcc_checking_assert (ref->use == IPA_REF_ALIAS); - if (symtab_function_p (ref->referred)) + if (is_a <cgraph_node> (ref->referred)) return ipa_ref_node (ref); return NULL; } @@ -1197,7 +1201,7 @@ varpool_alias_aliased_node (struct varpool_node *n) ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref); gcc_checking_assert (ref->use == IPA_REF_ALIAS); - if (symtab_variable_p (ref->referred)) + if (is_a <varpool_node> (ref->referred)) return ipa_ref_varpool_node (ref); return NULL; } @@ -1328,7 +1332,7 @@ symtab_real_symbol_p (symtab_node node) struct cgraph_node *cnode; struct ipa_ref *ref; - if (!symtab_function_p (node)) + if (!is_a <cgraph_node> (node)) return true; cnode = cgraph (node); if (cnode->global.inlined_to) |