From 5d59b5e18a878c2201471e529c40f15d49905fc8 Mon Sep 17 00:00:00 2001 From: Lawrence Crowl Date: Wed, 31 Oct 2012 23:15:10 +0000 Subject: [PATCH] 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 (pointer) Tests whether the pointer actually points to a more derived TYPE. TYPE *as_a (pointer) Converts pointer to a TYPE*. TYPE *dyn_cast (pointer) Converts pointer to TYPE* if and only if "is_a 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 (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 (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 and is_a . 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 * is-a.h: New. (is_a (U*)): New. Test for is-a relationship. (as_a (U*)): New. Treat as a derived type. (dyn_cast (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 ::test (symtab_node_def *)): New. (is_a_helper ::test (symtab_node_def *)): New. (symtab_node_def::try_function): New. Change most calls to symtab_function_p with calls to dyn_cast (p). (symtab_node_def::try_variable): New. Change most calls to symtab_variable_p with calls to dyn_cast (p). (symtab_function_p): Remove. Change callers to use is_a (p) instead. (symtab_variable_p): Remove. Change callers to use is_a (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 --- gcc/ChangeLog | 26 +++++ gcc/Makefile.in | 2 +- gcc/ada/gcc-interface/utils.c | 2 +- gcc/cgraph.c | 13 ++- gcc/cgraph.h | 114 +++++++++---------- gcc/cgraphbuild.c | 12 +- gcc/cgraphunit.c | 91 +++++++++------ gcc/cp/decl2.c | 4 +- gcc/ipa-inline-analysis.c | 19 ++-- gcc/ipa-ref.c | 2 +- gcc/ipa-reference.c | 34 +++--- gcc/ipa.c | 24 ++-- gcc/is-a.h | 201 ++++++++++++++++++++++++++++++++++ gcc/lto-cgraph.c | 41 +++---- gcc/lto-streamer-out.c | 8 +- gcc/lto-streamer.h | 8 +- gcc/lto-symtab.c | 10 +- gcc/lto/lto-partition.c | 32 +++--- gcc/lto/lto.c | 15 ++- gcc/passes.c | 2 +- gcc/symtab.c | 33 +++--- gcc/tree-emutls.c | 4 +- gcc/varasm.c | 4 +- gcc/varpool.c | 37 ++++--- 24 files changed, 499 insertions(+), 239 deletions(-) create mode 100644 gcc/is-a.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2d61cc2a4ec..ead3e1ae632 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2012-10-31 Lawrence Crowl + + * is-a.h: New. + (is_a (U*)): New. Test for is-a relationship. + (as_a (U*)): New. Treat as a derived type. + (dyn_cast (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 ::test (symtab_node_def *)): New. + (is_a_helper ::test (symtab_node_def *)): New. + (symtab_node_def::try_function): New. Change most calls to + symtab_function_p with calls to dyn_cast (p). + (symtab_node_def::try_variable): New. Change most calls to + symtab_variable_p with calls to dyn_cast (p). + (symtab_function_p): Remove. Change callers to use + is_a (p) instead. + (symtab_variable_p): Remove. Change callers to use + is_a (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. + 2012-10-31 Steven Bosscher Jakub Jelinek diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 96765fe3dd0..3a8ffbea6d8 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -886,7 +886,7 @@ CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) vecprim.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) + cif-code.def ipa-ref.h ipa-ref-inline.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) VALTRACK_H = valtrack.h $(BITMAP_H) $(DF_H) $(RTL_H) $(BASIC_BLOCK_H) \ diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 624e724f23c..43a835647d2 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -5586,7 +5586,7 @@ gnat_write_global_declarations (void) void_type_node); TREE_STATIC (dummy_global) = 1; TREE_ASM_WRITTEN (dummy_global) = 1; - node = varpool_node (dummy_global); + node = varpool_node_for_decl (dummy_global); node->symbol.force_output = 1; while (!VEC_empty (tree, types_used_by_cur_var_decl)) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 6e7b7c4fa3d..766609b5366 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -503,12 +503,15 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED, struct cgraph_node * cgraph_node_for_asm (tree asmname) { - symtab_node node = symtab_node_for_asm (asmname); - /* We do not want to look at inline clones. */ - for (node = symtab_node_for_asm (asmname); node; node = node->symbol.next_sharing_asm_name) - if (symtab_function_p (node) && !cgraph(node)->global.inlined_to) - return cgraph (node); + for (symtab_node node = symtab_node_for_asm (asmname); + node; + node = node->symbol.next_sharing_asm_name) + { + cgraph_node *cn = dyn_cast (node); + if (cn && !cn->global.inlined_to) + return cn; + } return NULL; } 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 ::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 ::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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (node)) return true; cnode = cgraph (node); if (cnode->global.inlined_to) diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index ce8f2ee080a..57167fd001d 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -84,7 +84,7 @@ record_reference (tree *tp, int *walk_subtrees, void *data) if (TREE_CODE (decl) == VAR_DECL) { - struct varpool_node *vnode = varpool_node (decl); + struct varpool_node *vnode = varpool_node_for_decl (decl); ipa_record_reference ((symtab_node)ctx->varpool_node, (symtab_node)vnode, IPA_REF_ADDR, NULL); @@ -123,7 +123,7 @@ record_type_list (struct cgraph_node *node, tree list) type = TREE_OPERAND (type, 0); if (TREE_CODE (type) == VAR_DECL) { - struct varpool_node *vnode = varpool_node (type); + struct varpool_node *vnode = varpool_node_for_decl (type); ipa_record_reference ((symtab_node)node, (symtab_node)vnode, IPA_REF_ADDR, NULL); @@ -233,7 +233,7 @@ mark_address (gimple stmt, tree addr, void *data) else if (addr && TREE_CODE (addr) == VAR_DECL && (TREE_STATIC (addr) || DECL_EXTERNAL (addr))) { - struct varpool_node *vnode = varpool_node (addr); + struct varpool_node *vnode = varpool_node_for_decl (addr); ipa_record_reference ((symtab_node)data, (symtab_node)vnode, @@ -262,7 +262,7 @@ mark_load (gimple stmt, tree t, void *data) else if (t && TREE_CODE (t) == VAR_DECL && (TREE_STATIC (t) || DECL_EXTERNAL (t))) { - struct varpool_node *vnode = varpool_node (t); + struct varpool_node *vnode = varpool_node_for_decl (t); ipa_record_reference ((symtab_node)data, (symtab_node)vnode, @@ -280,7 +280,7 @@ mark_store (gimple stmt, tree t, void *data) if (t && TREE_CODE (t) == VAR_DECL && (TREE_STATIC (t) || DECL_EXTERNAL (t))) { - struct varpool_node *vnode = varpool_node (t); + struct varpool_node *vnode = varpool_node_for_decl (t); ipa_record_reference ((symtab_node)data, (symtab_node)vnode, @@ -392,7 +392,7 @@ void record_references_in_initializer (tree decl, bool only_vars) { struct pointer_set_t *visited_nodes = pointer_set_create (); - struct varpool_node *node = varpool_node (decl); + struct varpool_node *node = varpool_node_for_decl (decl); struct record_reference_ctx ctx = {false, NULL}; ctx.varpool_node = node; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 64460ac63b7..230125c4a69 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -386,7 +386,8 @@ referred_to_p (symtab_node node) if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref)) return true; /* For functions check also calls. */ - if (symtab_function_p (node) && cgraph (node)->callers) + cgraph_node *cn = dyn_cast (node); + if (cn && cn->callers) return true; return false; } @@ -809,7 +810,7 @@ process_function_and_variable_attributes (struct cgraph_node *first, void varpool_finalize_decl (tree decl) { - struct varpool_node *node = varpool_node (decl); + struct varpool_node *node = varpool_node_for_decl (decl); gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl)); @@ -836,6 +837,35 @@ varpool_finalize_decl (tree decl) varpool_assemble_decl (node); } + +/* Determine if a symbol NODE is finalized and needed. */ + +inline static bool +symbol_finalized_and_needed (symtab_node node) +{ + if (cgraph_node *cnode = dyn_cast (node)) + return cnode->local.finalized + && cgraph_decide_is_function_needed (cnode, cnode->symbol.decl); + if (varpool_node *vnode = dyn_cast (node)) + return vnode->finalized + && !DECL_EXTERNAL (vnode->symbol.decl) + && decide_is_variable_needed (vnode, vnode->symbol.decl); + return false; +} + +/* Determine if a symbol NODE is finalized. */ + +inline static bool +symbol_finalized (symtab_node node) +{ + if (cgraph_node *cnode= dyn_cast (node)) + return cnode->local.finalized; + if (varpool_node *vnode = dyn_cast (node)) + return vnode->finalized; + return false; +} + + /* Discover all functions and variables that are trivially needed, analyze them as well as all functions and variables referred by them */ @@ -870,13 +900,7 @@ cgraph_analyze_functions (void) node != (symtab_node)first_analyzed && node != (symtab_node)first_analyzed_var; node = node->symbol.next) { - if ((symtab_function_p (node) - && cgraph (node)->local.finalized - && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl)) - || (symtab_variable_p (node) - && varpool (node)->finalized - && !DECL_EXTERNAL (node->symbol.decl) - && decide_is_variable_needed (varpool (node), node->symbol.decl))) + if (symbol_finalized_and_needed (node)) { enqueue_node (node); if (!changed && cgraph_dump_file) @@ -903,18 +927,15 @@ cgraph_analyze_functions (void) changed = true; node = first; first = (symtab_node)first->symbol.aux; - if (symtab_function_p (node) && cgraph (node)->local.finalized) + cgraph_node *cnode = dyn_cast (node); + if (cnode && cnode->local.finalized) { struct cgraph_edge *edge; - struct cgraph_node *cnode; - tree decl; + tree decl = cnode->symbol.decl; - cnode = cgraph (node); - decl = cnode->symbol.decl; - - /* ??? It is possible to create extern inline function and later using - weak alias attribute to kill its body. See - gcc.c-torture/compile/20011119-1.c */ + /* ??? It is possible to create extern inline function + and later using weak alias attribute to kill its body. + See gcc.c-torture/compile/20011119-1.c */ if (!DECL_STRUCT_FUNCTION (decl) && (!cnode->alias || !cnode->thunk.alias) && !cnode->thunk.thunk_p) @@ -929,23 +950,25 @@ cgraph_analyze_functions (void) for (edge = cnode->callees; edge; edge = edge->next_callee) if (edge->callee->local.finalized) - enqueue_node ((symtab_node)edge->callee); + enqueue_node ((symtab_node)edge->callee); - /* If decl is a clone of an abstract function, mark that abstract - function so that we don't release its body. The DECL_INITIAL() of that - abstract function declaration will be later needed to output debug - info. */ + /* If decl is a clone of an abstract function, + mark that abstract function so that we don't release its body. + The DECL_INITIAL() of that abstract function declaration + will be later needed to output debug info. */ if (DECL_ABSTRACT_ORIGIN (decl)) { - struct cgraph_node *origin_node; - origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl)); + struct cgraph_node *origin_node + = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl)); origin_node->abstract_and_needed = true; } - } - else if (symtab_variable_p (node) - && varpool (node)->finalized) - varpool_analyze_node (varpool (node)); + else + { + varpool_node *vnode = dyn_cast (node); + if (vnode && vnode->finalized) + varpool_analyze_node (vnode); + } if (node->symbol.same_comdat_group) { @@ -956,8 +979,7 @@ cgraph_analyze_functions (void) enqueue_node (next); } for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++) - if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized) - || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized)) + if (symbol_finalized (ref->referred)) enqueue_node (ref->referred); cgraph_process_new_functions (); } @@ -985,10 +1007,9 @@ cgraph_analyze_functions (void) symtab_remove_node (node); continue; } - if (symtab_function_p (node)) + if (cgraph_node *cnode = dyn_cast (node)) { tree decl = node->symbol.decl; - struct cgraph_node *cnode = cgraph (node); if (cnode->local.finalized && !gimple_has_body_p (decl) && (!cnode->alias || !cnode->thunk.alias) @@ -1070,7 +1091,7 @@ handle_alias_pairs (void) } if (TREE_CODE (p->decl) == FUNCTION_DECL - && target_node && symtab_function_p (target_node)) + && target_node && is_a (target_node)) { struct cgraph_node *src_node = cgraph_get_node (p->decl); if (src_node && src_node->local.finalized) @@ -1079,7 +1100,7 @@ handle_alias_pairs (void) VEC_unordered_remove (alias_pair, alias_pairs, i); } else if (TREE_CODE (p->decl) == VAR_DECL - && target_node && symtab_variable_p (target_node)) + && target_node && is_a (target_node)) { varpool_create_variable_alias (p->decl, target_node->symbol.decl); VEC_unordered_remove (alias_pair, alias_pairs, i); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 8657712916a..f3ce643e12e 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1775,7 +1775,7 @@ import_export_class (tree ctype) static bool var_finalized_p (tree var) { - return varpool_node (var)->finalized; + return varpool_node_for_decl (var)->finalized; } /* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason, @@ -1893,7 +1893,7 @@ maybe_emit_vtables (tree ctype) TREE_ASM_WRITTEN (vtbl) = 1; else if (DECL_ONE_ONLY (vtbl)) { - current = varpool_node (vtbl); + current = varpool_node_for_decl (vtbl); if (last) symtab_add_to_same_comdat_group ((symtab_node) current, (symtab_node) last); last = current; diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 8baaced2bd9..3de1439ab52 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -3855,22 +3855,25 @@ void inline_write_summary (void) { struct cgraph_node *node; - symtab_node snode; struct output_block *ob = create_output_block (LTO_section_inline_summary); lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder; unsigned int count = 0; int i; for (i = 0; i < lto_symtab_encoder_size (encoder); i++) - if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i)) - && cgraph (snode)->analyzed) - count++; + { + symtab_node snode = lto_symtab_encoder_deref (encoder, i); + cgraph_node *cnode = dyn_cast (snode); + if (cnode && cnode->analyzed) + count++; + } streamer_write_uhwi (ob, count); for (i = 0; i < lto_symtab_encoder_size (encoder); i++) { - if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i)) - && (node = cgraph (snode))->analyzed) + symtab_node snode = lto_symtab_encoder_deref (encoder, i); + cgraph_node *cnode = dyn_cast (snode); + if (cnode && (node = cnode)->analyzed) { struct inline_summary *info = inline_summary (node); struct bitpack_d bp; @@ -3878,7 +3881,7 @@ inline_write_summary (void) int i; size_time_entry *e; struct condition *c; - + streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, (symtab_node)node)); streamer_write_hwi (ob, info->estimated_self_stack_size); streamer_write_hwi (ob, info->self_size); @@ -3897,7 +3900,7 @@ inline_write_summary (void) bp_pack_value (&bp, c->by_ref, 1); streamer_write_bitpack (&bp); if (c->agg_contents) - streamer_write_uhwi (ob, c->offset); + streamer_write_uhwi (ob, c->offset); } streamer_write_uhwi (ob, VEC_length (size_time_entry, info->entry)); for (i = 0; diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c index 21799ab3a15..52850c6f872 100644 --- a/gcc/ipa-ref.c +++ b/gcc/ipa-ref.c @@ -42,7 +42,7 @@ ipa_record_reference (symtab_node referring_node, struct ipa_ref_list *list, *list2; VEC(ipa_ref_t,gc) *old_references; - gcc_checking_assert (!stmt || symtab_function_p (referring_node)); + gcc_checking_assert (!stmt || is_a (referring_node)); gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt); list = &referring_node->symbol.ref_list; diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c index 9072fe82199..a17d75b890a 100644 --- a/gcc/ipa-reference.c +++ b/gcc/ipa-reference.c @@ -482,7 +482,7 @@ analyze_function (struct cgraph_node *fn) local = init_function_info (fn); for (i = 0; ipa_ref_list_reference_iterate (&fn->symbol.ref_list, i, ref); i++) { - if (!symtab_variable_p (ref->referred)) + if (!is_a (ref->referred)) continue; var = ipa_ref_varpool_node (ref)->symbol.decl; if (!is_proper_for_analysis (var)) @@ -979,8 +979,6 @@ stream_out_bitmap (struct lto_simple_output_block *ob, static void ipa_reference_write_optimization_summary (void) { - struct cgraph_node *node; - symtab_node snode; struct lto_simple_output_block *ob = lto_create_simple_output_block (LTO_section_ipa_reference); unsigned int count = 0; @@ -994,12 +992,10 @@ ipa_reference_write_optimization_summary (void) /* See what variables we are interested in. */ for (i = 0; i < lto_symtab_encoder_size (encoder); i++) { - struct varpool_node *vnode; - snode = lto_symtab_encoder_deref (encoder, i); - if (!symtab_variable_p (snode)) - continue; - vnode = varpool (snode); - if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl)) + symtab_node snode = lto_symtab_encoder_deref (encoder, i); + varpool_node *vnode = dyn_cast (snode); + if (vnode + && bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl)) && referenced_from_this_partition_p (&vnode->symbol.ref_list, encoder)) { tree decl = vnode->symbol.decl; @@ -1013,10 +1009,12 @@ ipa_reference_write_optimization_summary (void) if (ltrans_statics_bitcount) for (i = 0; i < lto_symtab_encoder_size (encoder); i++) - if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i)) - && write_node_summary_p (cgraph (snode), - encoder, ltrans_statics)) + { + symtab_node snode = lto_symtab_encoder_deref (encoder, i); + cgraph_node *cnode = dyn_cast (snode); + if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics)) count++; + } streamer_write_uhwi_stream (ob->main_stream, count); if (count) @@ -1027,17 +1025,15 @@ ipa_reference_write_optimization_summary (void) if (ltrans_statics_bitcount) for (i = 0; i < lto_symtab_encoder_size (encoder); i++) { - snode = lto_symtab_encoder_deref (encoder, i); - if (!symtab_function_p (snode)) - continue; - node = cgraph (snode); - if (write_node_summary_p (node, encoder, ltrans_statics)) + symtab_node snode = lto_symtab_encoder_deref (encoder, i); + cgraph_node *cnode = dyn_cast (snode); + if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics)) { ipa_reference_optimization_summary_t info; int node_ref; - info = get_reference_optimization_summary (node); - node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node); + info = get_reference_optimization_summary (cnode); + node_ref = lto_symtab_encoder_encode (encoder, snode); streamer_write_uhwi_stream (ob->main_stream, node_ref); stream_out_bitmap (ob, info->statics_not_read, ltrans_statics, 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 (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 (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 (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 (ref->referring)) return true; node = ipa_ref_referring_varpool_node (ref); if (!DECL_VIRTUAL_P (node->symbol.decl)) diff --git a/gcc/is-a.h b/gcc/is-a.h new file mode 100644 index 00000000000..c5c75b4bc87 --- /dev/null +++ b/gcc/is-a.h @@ -0,0 +1,201 @@ +/* Dynamic testing for abstract is-a relationships. + Copyright (C) 2012 Free Software Foundation, Inc. + Contributed by Lawrence Crowl. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +/* This header generic type query and conversion functions. + + +USING THE GENERIC TYPE FACILITY + + +The user functions are: + +bool is_a (pointer) + + Tests whether the pointer actually points to a more derived TYPE. + + Suppose you have a symtab_node_def *ptr, AKA symtab_node ptr. You can test + whether it points to a 'derived' cgraph_node as follows. + + if (is_a (ptr)) + .... + + +TYPE *as_a (pointer) + + Converts pointer to a TYPE*. + + You can just assume that it is such a node. + + do_something_with (as_a *ptr); + +TYPE *dyn_cast (pointer) + + Converts pointer to TYPE* if and only if "is_a pointer". Otherwise, + returns NULL. This function is essentially a checked down cast. + + This functions reduce compile time and increase type safety when treating a + generic item as a more specific item. + + You can test and obtain a pointer to the 'derived' type in one indivisible + operation. + + if (cgraph_node *cptr = dyn_cast (ptr)) + .... + + As an example, the code change is from + + if (symtab_function_p (node)) + { + struct cgraph_node *cnode = cgraph (node); + .... + } + + to + + if (cgraph_node *cnode = dyn_cast (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 approach + 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 (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. + + +If you use these functions and get a 'inline function not defined' or a +'missing symbol' error message for 'is_a_helper<....>::test', it means that +the connection between the types has not been made. See below. + + +EXTENDING THE GENERIC TYPE FACILITY + +Each connection between types must be made by defining a specialization of the +template member function 'test' of the template class 'is_a_helper'. For +example, + + template <> + template <> + inline bool + is_a_helper ::test (symtab_node_def *p) + { + return p->symbol.type == SYMTAB_FUNCTION; + } + +If a simple reinterpret_cast between the pointer types is incorrect, then you +must also specialize the template member function 'cast'. Failure to do so +when needed may result in a crash. For example, + + template <> + template <> + inline bool + is_a_helper ::cast (symtab_node_def *p) + { + return &p->x_function; + } + +*/ + +#ifndef GCC_IS_A_H +#define GCC_IS_A_H + +/* A generic type conversion internal helper class. */ + +template +struct is_a_helper +{ + template + static inline bool test (U *p); + template + static inline T *cast (U *p); +}; + +/* Note that we deliberately do not define the 'test' member template. Not + doing so will result in a build-time error for type relationships that have + not been defined, rather than a run-time error. See the discussion above + for when to define this member. */ + +/* This is the generic implementation for casting from one type to another. + Do not use this routine directly; it is an internal function. See the + discussion above for when to define this member. */ + +template +template +inline T * +is_a_helper ::cast (U *p) +{ + return reinterpret_cast (p); +} + + +/* The public interface. */ + +/* A generic test for a type relationship. See the discussion above for when + to use this function. The question answered is "Is type T a derived type of + type U?". */ + +template +inline bool +is_a (U *p) +{ + return is_a_helper::test (p); +} + +/* A generic conversion from a base type U to a derived type T. See the + discussion above for when to use this function. */ + +template +inline T * +as_a (U *p) +{ + gcc_assert (is_a (p)); + return is_a_helper ::cast (p); +} + +/* A generic checked conversion from a base type U to a derived type T. See + the discussion above for when to use this function. */ + +template +inline T * +dyn_cast (U *p) +{ + if (is_a (p)) + return is_a_helper ::cast (p); + else + return static_cast (0); +} + +#endif /* GCC_IS_A_H */ diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index b23f192e3bd..e8f171824a1 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -679,7 +679,7 @@ add_references (lto_symtab_encoder_t encoder, int i; 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 (ref->referred)) add_node_to (encoder, ipa_ref_node (ref), false); else lto_symtab_encoder_encode (encoder, ref->referred); @@ -730,9 +730,8 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) for (i = 0; i < lto_symtab_encoder_size (encoder); i++) { symtab_node node = lto_symtab_encoder_deref (encoder, i); - if (symtab_variable_p (node)) + if (varpool_node *vnode = dyn_cast (node)) { - struct varpool_node *vnode = varpool (node); if (DECL_INITIAL (vnode->symbol.decl) && !lto_symtab_encoder_encode_initializer_p (encoder, vnode) @@ -796,8 +795,8 @@ output_symtab (void) for (i = 0; i < n_nodes; i++) { symtab_node node = lto_symtab_encoder_deref (encoder, i); - if (symtab_function_p (node)) - lto_output_node (ob, cgraph (node), encoder); + if (cgraph_node *cnode = dyn_cast (node)) + lto_output_node (ob, cnode, encoder); else lto_output_varpool_node (ob, varpool (node), encoder); @@ -983,7 +982,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, order = streamer_read_hwi (ib) + order_base; decl_index = streamer_read_uhwi (ib); var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index); - node = varpool_node (var_decl); + node = varpool_node_for_decl (var_decl); node->symbol.order = order; if (order >= symtab_order) symtab_order = order + 1; @@ -1144,14 +1143,14 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, /* AUX pointers should be all non-zero for function nodes read from the stream. */ #ifdef ENABLE_CHECKING FOR_EACH_VEC_ELT (symtab_node, nodes, i, node) - gcc_assert (node->symbol.aux || !symtab_function_p (node)); + gcc_assert (node->symbol.aux || !is_a (node)); #endif FOR_EACH_VEC_ELT (symtab_node, nodes, i, node) { int ref; - if (symtab_function_p (node)) + if (cgraph_node *cnode = dyn_cast (node)) { - ref = (int) (intptr_t) cgraph (node)->global.inlined_to; + ref = (int) (intptr_t) cnode->global.inlined_to; /* We share declaration of builtins, so we may read same node twice. */ if (!node->symbol.aux) @@ -1160,9 +1159,9 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, /* Fixup inlined_to from reference to pointer. */ if (ref != LCC_NOT_FOUND) - cgraph (node)->global.inlined_to = cgraph (VEC_index (symtab_node, nodes, ref)); + cnode->global.inlined_to = cgraph (VEC_index (symtab_node, nodes, ref)); else - cgraph (node)->global.inlined_to = NULL; + cnode->global.inlined_to = NULL; } ref = (int) (intptr_t) node->symbol.same_comdat_group; @@ -1174,7 +1173,7 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, node->symbol.same_comdat_group = NULL; } FOR_EACH_VEC_ELT (symtab_node, nodes, i, node) - node->symbol.aux = symtab_function_p (node) ? (void *)1 : NULL; + node->symbol.aux = is_a (node) ? (void *)1 : NULL; return nodes; } @@ -1449,7 +1448,6 @@ output_node_opt_summary (struct output_block *ob, static void output_cgraph_opt_summary (void) { - symtab_node node; int i, n_nodes; lto_symtab_encoder_t encoder; struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum); @@ -1459,18 +1457,21 @@ output_cgraph_opt_summary (void) encoder = ob->decl_state->symtab_node_encoder; n_nodes = lto_symtab_encoder_size (encoder); for (i = 0; i < n_nodes; i++) - if (symtab_function_p (node = lto_symtab_encoder_deref (encoder, i)) - && output_cgraph_opt_summary_p (cgraph (node))) - count++; + { + symtab_node node = lto_symtab_encoder_deref (encoder, i); + cgraph_node *cnode = dyn_cast (node); + if (cnode && output_cgraph_opt_summary_p (cnode)) + count++; + } streamer_write_uhwi (ob, count); for (i = 0; i < n_nodes; i++) { - node = lto_symtab_encoder_deref (encoder, i); - if (symtab_function_p (node) - && output_cgraph_opt_summary_p (cgraph (node))) + symtab_node node = lto_symtab_encoder_deref (encoder, i); + cgraph_node *cnode = dyn_cast (node); + if (cnode && output_cgraph_opt_summary_p (cnode)) { streamer_write_uhwi (ob, i); - output_node_opt_summary (ob, cgraph (node), encoder); + output_node_opt_summary (ob, cnode, encoder); } } produce_asm (ob, NULL); diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 806045b52bf..4467eb49e5a 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -956,7 +956,6 @@ copy_function (struct cgraph_node *node) static void lto_output (void) { - struct cgraph_node *node; struct lto_out_decl_state *decl_state; #ifdef ENABLE_CHECKING bitmap output = lto_bitmap_alloc (); @@ -972,10 +971,9 @@ lto_output (void) for (i = 0; i < n_nodes; i++) { symtab_node snode = lto_symtab_encoder_deref (encoder, i); - if (!symtab_function_p (snode)) - continue; - node = cgraph (snode); - if (lto_symtab_encoder_encode_body_p (encoder, node) + cgraph_node *node = dyn_cast (snode); + if (node + && lto_symtab_encoder_encode_body_p (encoder, node) && !node->alias && !node->thunk.thunk_p) { diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index c9d13aea4da..b45def70927 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -1115,7 +1115,7 @@ lsei_next_function_in_partition (lto_symtab_encoder_iterator *lsei) { lsei_next (lsei); while (!lsei_end_p (*lsei) - && (!symtab_function_p (lsei_node (*lsei)) + && (!is_a (lsei_node (*lsei)) || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node (*lsei)))) lsei_next (lsei); } @@ -1128,7 +1128,7 @@ lsei_start_function_in_partition (lto_symtab_encoder_t encoder) if (lsei_end_p (lsei)) return lsei; - if (!symtab_function_p (lsei_node (lsei)) + if (!is_a (lsei_node (lsei)) || !lto_symtab_encoder_in_partition_p (encoder, lsei_node (lsei))) lsei_next_function_in_partition (&lsei); @@ -1141,7 +1141,7 @@ lsei_next_variable_in_partition (lto_symtab_encoder_iterator *lsei) { lsei_next (lsei); while (!lsei_end_p (*lsei) - && (!symtab_variable_p (lsei_node (*lsei)) + && (!is_a (lsei_node (*lsei)) || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node (*lsei)))) lsei_next (lsei); } @@ -1154,7 +1154,7 @@ lsei_start_variable_in_partition (lto_symtab_encoder_t encoder) if (lsei_end_p (lsei)) return lsei; - if (!symtab_variable_p (lsei_node (lsei)) + if (!is_a (lsei_node (lsei)) || !lto_symtab_encoder_in_partition_p (encoder, lsei_node (lsei))) lsei_next_variable_in_partition (&lsei); diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index 659a68b68a5..737c38b0f39 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto-symtab.c @@ -532,11 +532,11 @@ lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing) if (!symtab_real_symbol_p (e)) continue; - if (symtab_function_p (e) - && !DECL_BUILT_IN (e->symbol.decl)) - lto_cgraph_replace_node (cgraph (e), cgraph (prevailing)); - if (symtab_variable_p (e)) - lto_varpool_replace_node (varpool (e), varpool (prevailing)); + cgraph_node *ce = dyn_cast (e); + if (ce && !DECL_BUILT_IN (e->symbol.decl)) + lto_cgraph_replace_node (ce, cgraph (prevailing)); + if (varpool_node *ve = dyn_cast (e)) + lto_varpool_replace_node (ve, varpool (prevailing)); } return; diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c index 32243fb83d3..a642a6c5f17 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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (ref->referring)) { int index; diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 7f64daee219..857e8f6032b 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 (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 (node); + if (vnode + && lto_symtab_encoder_encode_initializer_p (part->encoder, vnode)) + fprintf (cgraph_dump_file, "(initializer included)"); + } } } fprintf (cgraph_dump_file, "\n"); diff --git a/gcc/passes.c b/gcc/passes.c index 7a3d204e0d3..7ab58aa381b 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -201,7 +201,7 @@ rest_of_decl_compilation (tree decl, ; else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl) && TREE_STATIC (decl)) - varpool_node (decl); + varpool_node_for_decl (decl); } /* Called after finishing a record, union or enumeral type. */ diff --git a/gcc/symtab.c b/gcc/symtab.c index c21edcbb79d..39753e2204d 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -104,7 +104,7 @@ eq_assembler_name (const void *p1, const void *p2) static void insert_to_assembler_name_hash (symtab_node node) { - if (symtab_variable_p (node) && DECL_HARD_REGISTER (node->symbol.decl)) + if (is_a (node) && DECL_HARD_REGISTER (node->symbol.decl)) return; gcc_checking_assert (!node->symbol.previous_sharing_asm_name && !node->symbol.next_sharing_asm_name); @@ -252,8 +252,8 @@ symtab_unregister_node (symtab_node node) if (*slot == node) { symtab_node replacement_node = NULL; - if (symtab_function_p (node)) - replacement_node = (symtab_node)cgraph_find_replacement_node (cgraph (node)); + if (cgraph_node *cnode = dyn_cast (node)) + replacement_node = (symtab_node)cgraph_find_replacement_node (cnode); if (!replacement_node) htab_clear_slot (symtab_hash, slot); else @@ -294,10 +294,10 @@ symtab_get_node (const_tree decl) void symtab_remove_node (symtab_node node) { - if (symtab_function_p (node)) - cgraph_remove_node (cgraph (node)); - else if (symtab_variable_p (node)) - varpool_remove_node (varpool (node)); + if (cgraph_node *cnode = dyn_cast (node)) + cgraph_remove_node (cnode); + else if (varpool_node *vnode = dyn_cast (node)) + varpool_remove_node (vnode); } /* Initalize asm name hash unless. */ @@ -538,10 +538,10 @@ dump_symtab_base (FILE *f, symtab_node node) void dump_symtab_node (FILE *f, symtab_node node) { - if (symtab_function_p (node)) - dump_cgraph_node (f, cgraph (node)); - else if (symtab_variable_p (node)) - dump_varpool_node (f, varpool (node)); + if (cgraph_node *cnode = dyn_cast (node)) + dump_cgraph_node (f, cnode); + else if (varpool_node *vnode = dyn_cast (node)) + dump_varpool_node (f, vnode); } /* Dump symbol table. */ @@ -579,7 +579,7 @@ verify_symtab_base (symtab_node node) bool error_found = false; symtab_node hashed_node; - if (symtab_function_p (node)) + if (is_a (node)) { if (TREE_CODE (node->symbol.decl) != FUNCTION_DECL) { @@ -587,7 +587,7 @@ verify_symtab_base (symtab_node node) error_found = true; } } - else if (symtab_variable_p (node)) + else if (is_a (node)) { if (TREE_CODE (node->symbol.decl) != VAR_DECL) { @@ -622,7 +622,8 @@ verify_symtab_base (symtab_node node) hashed_node = hashed_node->symbol.next_sharing_asm_name; } if (!hashed_node - && !(symtab_variable_p (node) || DECL_HARD_REGISTER (node->symbol.decl))) + && !(is_a (node) + || DECL_HARD_REGISTER (node->symbol.decl))) { error ("node not found in symtab assembler name hash"); error_found = true; @@ -676,8 +677,8 @@ verify_symtab_node (symtab_node node) return; timevar_push (TV_CGRAPH_VERIFY); - if (symtab_function_p (node)) - verify_cgraph_node (cgraph (node)); + if (cgraph_node *cnode = dyn_cast (node)) + verify_cgraph_node (cnode); else if (verify_symtab_base (node)) { diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index de71b23f3c2..d2cd4ea7946 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -260,7 +260,7 @@ get_emutls_init_templ_addr (tree decl) /* Create varpool node for the new variable and finalize it if it is not external one. */ if (DECL_EXTERNAL (to)) - varpool_node (to); + varpool_node_for_decl (to); else varpool_add_new_variable (to); return build_fold_addr_expr (to); @@ -332,7 +332,7 @@ new_emutls_decl (tree decl, tree alias_of) /* Create varpool node for the new variable and finalize it if it is not external one. */ if (DECL_EXTERNAL (to)) - varpool_node (to); + varpool_node_for_decl (to); else if (!alias_of) varpool_add_new_variable (to); else diff --git a/gcc/varasm.c b/gcc/varasm.c index a587c80fd34..b3003485423 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2221,7 +2221,7 @@ mark_decl_referenced (tree decl) } else if (TREE_CODE (decl) == VAR_DECL) { - struct varpool_node *node = varpool_node (decl); + struct varpool_node *node = varpool_node_for_decl (decl); /* C++ frontend use mark_decl_references to force COMDAT variables to be output that might appear dead otherwise. */ node->symbol.force_output = true; @@ -5549,7 +5549,7 @@ assemble_alias (tree decl, tree target) if (TREE_CODE (decl) == FUNCTION_DECL) cgraph_get_create_node (decl)->alias = true; else - varpool_node (decl)->alias = true; + varpool_node_for_decl (decl)->alias = true; /* If the target has already been emitted, we don't have to queue the alias. This saves a tad of memory. */ diff --git a/gcc/varpool.c b/gcc/varpool.c index 314c66ee308..b88ec613ff6 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -39,7 +39,7 @@ along with GCC; see the file COPYING3. If not see /* Return varpool node assigned to DECL. Create new one when needed. */ struct varpool_node * -varpool_node (tree decl) +varpool_node_for_decl (tree decl) { struct varpool_node *node = varpool_get_node (decl); gcc_assert (TREE_CODE (decl) == VAR_DECL @@ -114,9 +114,9 @@ debug_varpool (void) struct varpool_node * varpool_node_for_asm (tree asmname) { - symtab_node node = symtab_node_for_asm (asmname); - if (node && symtab_variable_p (node)) - return varpool (node); + if (symtab_node node = symtab_node_for_asm (asmname)) + if (varpool_node *vnode = dyn_cast (node)) + return vnode; return NULL; } @@ -192,7 +192,7 @@ varpool_add_new_variable (tree decl) { struct varpool_node *node; varpool_finalize_decl (decl); - node = varpool_node (decl); + node = varpool_node_for_decl (decl); if (varpool_externally_visible_p (node, false)) node->symbol.externally_visible = true; } @@ -232,7 +232,7 @@ varpool_analyze_node (struct varpool_node *node) } if (node->alias && node->alias_of) { - struct varpool_node *tgt = varpool_node (node->alias_of); + struct varpool_node *tgt = varpool_node_for_decl (node->alias_of); struct varpool_node *n; for (n = tgt; n && n->alias; @@ -378,16 +378,21 @@ varpool_remove_unreferenced_decls (void) for (next = node->symbol.same_comdat_group; next != (symtab_node)node; next = next->symbol.same_comdat_group) - if (symtab_variable_p (next) - && varpool (next)->analyzed) - enqueue_node (varpool (next), &first); + { + varpool_node *vnext = dyn_cast (next); + if (vnext && vnext->analyzed) + enqueue_node (vnext, &first); + } } for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++) - if (symtab_variable_p (ref->referred) - && (!DECL_EXTERNAL (ref->referred->symbol.decl) - || varpool (ref->referred)->alias) - && varpool (ref->referred)->analyzed) - enqueue_node (varpool (ref->referred), &first); + { + varpool_node *vnode = dyn_cast (ref->referred); + if (vnode + && (!DECL_EXTERNAL (ref->referred->symbol.decl) + || vnode->alias) + && vnode->analyzed) + enqueue_node (vnode, &first); + } } if (cgraph_dump_file) fprintf (cgraph_dump_file, "\nRemoving variables:"); @@ -461,7 +466,7 @@ add_new_static_var (tree type) DECL_CONTEXT (new_decl) = NULL_TREE; DECL_ABSTRACT (new_decl) = 0; lang_hooks.dup_lang_specific_decl (new_decl); - new_node = varpool_node (new_decl); + new_node = varpool_node_for_decl (new_decl); varpool_finalize_decl (new_decl); return new_node->symbol.decl; @@ -477,7 +482,7 @@ varpool_create_variable_alias (tree alias, tree decl) gcc_assert (TREE_CODE (decl) == VAR_DECL); gcc_assert (TREE_CODE (alias) == VAR_DECL); - alias_node = varpool_node (alias); + alias_node = varpool_node_for_decl (alias); alias_node->alias = 1; alias_node->finalized = 1; alias_node->alias_of = decl;