diff options
Diffstat (limited to 'gcc/cgraph.h')
-rw-r--r-- | gcc/cgraph.h | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 3d6f3876f9c..a6a0a2438f7 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -300,10 +300,12 @@ struct GTY(()) cgraph_node { int count_materialization_scale; /* Unique id of the node. */ int uid; + /* ID assigned by the profiling. */ + unsigned int profile_id; /* Set when decl is an abstract function pointed to by the ABSTRACT_DECL_ORIGIN of a reachable function. */ - unsigned abstract_and_needed : 1; + unsigned used_as_abstract_origin : 1; /* Set once the function is lowered (i.e. its CFG is built). */ unsigned lowered : 1; /* Set once the function has been instantiated and its callee @@ -433,6 +435,10 @@ struct GTY(()) cgraph_indirect_call_info int param_index; /* ECF flags determined from the caller. */ int ecf_flags; + /* Profile_id of common target obtrained from profile. */ + int common_target_id; + /* Probability that call will land in function with COMMON_TARGET_ID. */ + int common_target_probability; /* Set when the call is a virtual call with the parameter being the associated object pointer rather than a simple direct call. */ @@ -483,6 +489,24 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap unsigned int call_stmt_cannot_inline_p : 1; /* Can this call throw externally? */ unsigned int can_throw_external : 1; + /* Edges with SPECULATIVE flag represents indirect calls that was + speculatively turned into direct (i.e. by profile feedback). + The final code sequence will have form: + + if (call_target == expected_fn) + expected_fn (); + else + call_target (); + + Every speculative call is represented by three components attached + to a same call statement: + 1) a direct call (to expected_fn) + 2) an indirect call (to call_target) + 3) a IPA_REF_ADDR refrence to expected_fn. + + Optimizers may later redirect direct call to clone, so 1) and 3) + do not need to necesarily agree with destination. */ + unsigned int speculative : 1; }; #define CGRAPH_FREQ_BASE 1000 @@ -597,6 +621,13 @@ symtab_node symtab_alias_ultimate_target (symtab_node, enum availability *avail = NULL); bool symtab_resolve_alias (symtab_node node, symtab_node target); void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target); +bool symtab_for_node_and_aliases (symtab_node, + bool (*) (symtab_node, void *), + void *, + bool); +symtab_node symtab_nonoverwritable_alias (symtab_node); +enum availability symtab_node_availability (symtab_node); +bool symtab_semantically_equivalent_p (symtab_node, symtab_node); /* In cgraph.c */ void dump_cgraph (FILE *); @@ -606,6 +637,7 @@ void debug_cgraph_node (struct cgraph_node *); void cgraph_remove_edge (struct cgraph_edge *); void cgraph_remove_node (struct cgraph_node *); void cgraph_release_function_body (struct cgraph_node *); +void release_function_body (tree); void cgraph_node_remove_callees (struct cgraph_node *node); struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, struct cgraph_node *, @@ -622,7 +654,7 @@ struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, H HOST_WIDE_INT, tree, tree); struct cgraph_node *cgraph_node_for_asm (tree); struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple); -void cgraph_set_call_stmt (struct cgraph_edge *, gimple); +void cgraph_set_call_stmt (struct cgraph_edge *, gimple, bool update_speculative = true); void cgraph_update_edges_for_call_stmt (gimple, tree, gimple); struct cgraph_local_info *cgraph_local_info (tree); struct cgraph_global_info *cgraph_global_info (tree); @@ -634,7 +666,7 @@ void cgraph_call_edge_duplication_hooks (struct cgraph_edge *, struct cgraph_edge *); void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *); -void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *); +struct cgraph_edge *cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *); bool cgraph_only_called_directly_p (struct cgraph_node *); bool cgraph_function_possibly_inlined_p (tree); @@ -669,12 +701,14 @@ void cgraph_mark_address_taken_node (struct cgraph_node *); typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *); typedef void (*cgraph_node_hook)(struct cgraph_node *, void *); +typedef void (*varpool_node_hook)(struct varpool_node *, void *); typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *, void *); typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *, void *); struct cgraph_edge_hook_list; struct cgraph_node_hook_list; +struct varpool_node_hook_list; struct cgraph_2edge_hook_list; struct cgraph_2node_hook_list; struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *); @@ -682,18 +716,32 @@ void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *); struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook, void *); void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *); +struct varpool_node_hook_list *varpool_add_node_removal_hook (varpool_node_hook, + void *); +void varpool_remove_node_removal_hook (struct varpool_node_hook_list *); struct cgraph_node_hook_list *cgraph_add_function_insertion_hook (cgraph_node_hook, void *); void cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *); +struct varpool_node_hook_list *varpool_add_variable_insertion_hook (varpool_node_hook, + void *); +void varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *); void cgraph_call_function_insertion_hooks (struct cgraph_node *node); struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *); void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *); struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *); void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *); gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *); -bool cgraph_propagate_frequency (struct cgraph_node *node); struct cgraph_node * cgraph_function_node (struct cgraph_node *, enum availability *avail = NULL); +bool cgraph_get_body (struct cgraph_node *node); +struct cgraph_edge * +cgraph_turn_edge_to_speculative (struct cgraph_edge *, + struct cgraph_node *, + gcov_type, int); +void cgraph_speculative_call_info (struct cgraph_edge *, + struct cgraph_edge *&, + struct cgraph_edge *&, + struct ipa_ref *&); /* In cgraphunit.c */ struct asm_node *add_asm_node (tree); @@ -709,6 +757,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree); IN_SSA is true if the gimple is in SSA. */ basic_block init_lowered_empty_function (tree, bool); void cgraph_reset_node (struct cgraph_node *); +void expand_thunk (struct cgraph_node *); /* In cgraphclones.c */ @@ -726,7 +775,8 @@ struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node, const char *clone_name); struct cgraph_node *cgraph_find_replacement_node (struct cgraph_node *); bool cgraph_remove_node_and_inline_clones (struct cgraph_node *, struct cgraph_node *); -void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple); +void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple, + bool update_speculative = true); void cgraph_create_edge_including_clones (struct cgraph_node *, struct cgraph_node *, gimple, gimple, gcov_type, int, @@ -741,6 +791,7 @@ struct cgraph_node *cgraph_function_versioning (struct cgraph_node *, basic_block, const char *); void tree_function_versioning (tree, tree, vec<ipa_replace_map_p, va_gc> *, bool, bitmap, bool, bitmap, basic_block); +struct cgraph_edge *cgraph_resolve_speculation (struct cgraph_edge *, tree); /* In cgraphbuild.c */ unsigned int rebuild_cgraph_edges (void); @@ -1347,13 +1398,25 @@ symtab_real_symbol_p (symtab_node node) { struct cgraph_node *cnode; + if (DECL_ABSTRACT (node->symbol.decl)) + return false; if (!is_a <cgraph_node> (node)) return true; cnode = cgraph (node); if (cnode->global.inlined_to) return false; - if (cnode->abstract_and_needed) - return false; return true; } + +/* Return true if NODE can be discarded by linker from the binary. */ + +static inline bool +symtab_can_be_discarded (symtab_node node) +{ + return (DECL_EXTERNAL (node->symbol.decl) + || (DECL_ONE_ONLY (node->symbol.decl) + && node->symbol.resolution != LDPR_PREVAILING_DEF + && node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY + && node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY_EXP)); +} #endif /* GCC_CGRAPH_H */ |