aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto
diff options
context:
space:
mode:
authorLawrence Crowl <crowl@google.com>2012-10-31 23:15:10 +0000
committerLawrence Crowl <crowl@gcc.gnu.org>2012-10-31 23:15:10 +0000
commit5d59b5e18a878c2201471e529c40f15d49905fc8 (patch)
tree7209857044c64b9be2543946aeb701d483464efa /gcc/lto
parent2a381a57f3061e171923a14083ac37d957c9c98d (diff)
downloadgcc-5d59b5e18a878c2201471e529c40f15d49905fc8.zip
gcc-5d59b5e18a878c2201471e529c40f15d49905fc8.tar.gz
gcc-5d59b5e18a878c2201471e529c40f15d49905fc8.tar.bz2
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. From-SVN: r193051
Diffstat (limited to 'gcc/lto')
-rw-r--r--gcc/lto/lto-partition.c32
-rw-r--r--gcc/lto/lto.c15
2 files changed, 25 insertions, 22 deletions
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 32243fb..a642a6c 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -55,22 +55,22 @@ get_symbol_class (symtab_node node)
{
/* Inline clones are always duplicated.
This include external delcarations. */
- if (symtab_function_p (node)
- && cgraph (node)->global.inlined_to)
+ cgraph_node *cnode = dyn_cast <cgraph_node> (node);
+ if (cnode && cnode->global.inlined_to)
return SYMBOL_DUPLICATE;
/* External declarations are external. */
if (DECL_EXTERNAL (node->symbol.decl))
return SYMBOL_EXTERNAL;
- if (symtab_variable_p (node))
+ if (varpool_node *vnode = dyn_cast <varpool_node> (node))
{
/* Constant pool references use local symbol names that can not
be promoted global. We should never put into a constant pool
objects that can not be duplicated across partitions. */
if (DECL_IN_CONSTANT_POOL (node->symbol.decl))
return SYMBOL_DUPLICATE;
- gcc_checking_assert (varpool (node)->analyzed);
+ gcc_checking_assert (vnode->analyzed);
}
/* Functions that are cloned may stay in callgraph even if they are unused.
Handle them as external; compute_ltrans_boundary take care to make
@@ -145,7 +145,7 @@ add_references_to_partition (ltrans_partition part, symtab_node node)
/* References to a readonly variable may be constant foled into its value.
Recursively look into the initializers of the constant variable and add
references, too. */
- else if (symtab_variable_p (ref->referred)
+ else if (is_a <varpool_node> (ref->referred)
&& const_value_known_p (ref->referred->symbol.decl)
&& !lto_symtab_encoder_in_partition_p (part->encoder, ref->referred))
{
@@ -196,9 +196,8 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node node)
}
node->symbol.aux = (void *)((size_t)node->symbol.aux + 1);
- if (symtab_function_p (node))
+ if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
{
- struct cgraph_node *cnode = cgraph (node);
struct cgraph_edge *e;
part->insns += inline_summary (cnode)->self_size;
@@ -247,15 +246,15 @@ contained_in_symbol (symtab_node node)
if (lookup_attribute ("weakref",
DECL_ATTRIBUTES (node->symbol.decl)))
return node;
- if (symtab_function_p (node))
+ if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
{
- struct cgraph_node *cnode = cgraph_function_node (cgraph (node), NULL);
+ cnode = cgraph_function_node (cnode, NULL);
if (cnode->global.inlined_to)
cnode = cnode->global.inlined_to;
return (symtab_node) cnode;
}
- else if (symtab_variable_p (node))
- return (symtab_node) varpool_variable_node (varpool (node), NULL);
+ else if (varpool_node *vnode = dyn_cast <varpool_node> (node))
+ return (symtab_node) varpool_variable_node (vnode, NULL);
return node;
}
@@ -302,8 +301,8 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
pointer_set_destroy (partition->initializers_visited);
partition->initializers_visited = NULL;
- if (symtab_function_p (node))
- partition->insns -= inline_summary (cgraph (node))->self_size;
+ if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
+ partition->insns -= inline_summary (cnode)->self_size;
lto_symtab_encoder_delete_node (partition->encoder, node);
node->symbol.aux = (void *)((size_t)node->symbol.aux - 1);
}
@@ -555,11 +554,10 @@ lto_balanced_map (void)
symtab_node snode = lto_symtab_encoder_deref (partition->encoder,
last_visited_node);
- if (symtab_function_p (snode))
+ if (cgraph_node *node = dyn_cast <cgraph_node> (snode))
{
struct cgraph_edge *edge;
- node = cgraph (snode);
refs = &node->symbol.ref_list;
last_visited_node++;
@@ -611,7 +609,7 @@ lto_balanced_map (void)
/* 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++)
- if (symtab_variable_p (ref->referred))
+ if (is_a <varpool_node> (ref->referred))
{
int index;
@@ -645,7 +643,7 @@ lto_balanced_map (void)
cost++;
}
for (j = 0; ipa_ref_list_referring_iterate (refs, j, ref); j++)
- if (symtab_variable_p (ref->referring))
+ if (is_a <varpool_node> (ref->referring))
{
int index;
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 7f64dae..857e8f6 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -2671,12 +2671,17 @@ lto_wpa_write_files (void)
if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
{
fprintf (cgraph_dump_file, "%s ", symtab_node_asm_name (node));
- if (symtab_function_p (node)
- && lto_symtab_encoder_encode_body_p (part->encoder, cgraph (node)))
+ cgraph_node *cnode = dyn_cast <cgraph_node> (node);
+ if (cnode
+ && lto_symtab_encoder_encode_body_p (part->encoder, cnode))
fprintf (cgraph_dump_file, "(body included)");
- else if (symtab_variable_p (node)
- && lto_symtab_encoder_encode_initializer_p (part->encoder, varpool (node)))
- fprintf (cgraph_dump_file, "(initializer included)");
+ else
+ {
+ varpool_node *vnode = dyn_cast <varpool_node> (node);
+ if (vnode
+ && lto_symtab_encoder_encode_initializer_p (part->encoder, vnode))
+ fprintf (cgraph_dump_file, "(initializer included)");
+ }
}
}
fprintf (cgraph_dump_file, "\n");