GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "cgraph.h"
#include "lto-streamer.h"
#include "fold-const.h"
#include "print-tree.h"
#include "calls.h"
#include "ipa-utils.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "symbol-summary.h"
#include "tree-vrp.h"
#include "sreal.h"
#include "ipa-cp.h"
#include "ipa-prop.h"
#include "ipa-fnsummary.h"
#include "demangle.h"
#include "dbgcnt.h"
#include "gimple-pretty-print.h"
#include "intl.h"
#include "stringpool.h"
#include "attribs.h"
#include "data-streamer.h"
#include "streamer-hooks.h"
#include "gt-ipa-devirt.h"
Data Structures | |
struct | type_pair |
struct | default_hash_traits< type_pair > |
struct | odr_type_d |
struct | odr_name_hasher |
struct | odr_enum_val |
struct | odr_enum |
class | polymorphic_call_target_d |
struct | polymorphic_call_target_hasher |
struct | odr_type_warn_count |
struct | decl_warn_count |
class | final_warning_record |
Macros | |
#define | odr_types (*odr_types_ptr) |
Typedefs | |
typedef hash_table< odr_name_hasher > | odr_hash_type |
typedef hash_table< polymorphic_call_target_hasher > | polymorphic_call_target_hash_type |
Variables | |
bool | thunk_expansion |
static bool | odr_violation_reported = false |
static hash_set< cgraph_node * > * | cached_polymorphic_call_targets |
static odr_hash_type * | odr_hash |
static vec< odr_type, va_gc > * | odr_types_ptr |
static vec< tree, va_gc > * | odr_enums |
static hash_map< nofree_string_hash, odr_enum > * | odr_enum_map = NULL |
static struct obstack | odr_enum_obstack |
static polymorphic_call_target_hash_type * | polymorphic_call_target_hash |
class final_warning_record * | final_warning_records |
#define odr_types (*odr_types_ptr) |
typedef hash_table<odr_name_hasher> odr_hash_type |
ODR type hash used to look up ODR type based on tree type node.
Polymorphic call target query cache.
bool add_decl_warning | ( | const tree & | key, |
const decl_warn_count & | value, | ||
vec< const decl_warn_count * > * | vec ) |
Referenced by ipa_devirt().
TYPE is equivalent to VAL by ODR, but its tree representation differs from VAL->type. This may happen in LTO where tree merging did not merge all variants of the same type or due to ODR violation. Analyze and report ODR violations and add type to duplicate list. If TYPE is more specified than VAL->type, prevail VAL->type. Also if this is first time we see definition of a class return true so the base types are analyzed.
References hash_set< KeyId, Lazy, Traits >::add(), lto_location_cache::apply_location_cache(), odr_type_d::bases, BINFO_BASE_BINFO, BINFO_N_BASE_BINFOS, BINFO_OFFSET, BINFO_TYPE, BINFO_VTABLE, can_be_name_hashed_p(), COMPLETE_TYPE_P, lto_location_cache::current_cache, DECL_ASSEMBLER_NAME, DECL_EXTERNAL, DECL_SOURCE_LOCATION, symbol_table::dump_file, gcc_assert, gcc_checking_assert, get_odr_type(), i, inform(), NULL, odr_hash, odr_types_equivalent_p(), odr_type_d::odr_violated, odr_violation_reported, operand_equal_p(), polymorphic_type_binfo_p(), print_node(), set_type_binfo(), symtab, TREE_CODE, TREE_OPERAND, odr_type_d::type, TYPE_BINFO, TYPE_MAIN_VARIANT, TYPE_NAME, odr_type_d::types, types_odr_comparable(), types_same_for_odr(), odr_type_d::types_set, UNKNOWN_LOCATION, vec_safe_push(), visited, warn_odr(), and warn_types_mismatch().
Referenced by get_odr_type().
void build_type_inheritance_graph | ( | void | ) |
Initialize IPA devirt and build inheritance tree graph.
References symtab_node::decl, DECL_CONTEXT, DECL_VIRTUAL_P, dump_begin(), dump_end(), dump_type_inheritance_graph(), FOR_EACH_SYMBOL, free_odr_warning_data(), get_odr_type(), is_a(), odr_hash, polymorphic_type_binfo_p(), symtab_node::real_symbol_p(), TDI_inheritance, timevar_pop(), timevar_push(), TREE_CODE, TREE_TYPE, TYPE_BINFO, TYPE_MAIN_VARIANT, and TYPE_METHOD_BASETYPE.
Referenced by analyze_functions(), and symbol_table::remove_unreachable_nodes().
References odr_type_p().
Referenced by add_type_duplicate(), and get_odr_type().
void compare_virtual_tables | ( | varpool_node * | prevailing, |
varpool_node * | vtable ) |
Compare two virtual tables, PREVAILING and VTABLE and output ODR violation warnings.
References symtab_node::decl, DECL_CONTEXT, DECL_SIZE, DECL_SOURCE_LOCATION, DECL_VIRTUAL_P, symtab_node::definition, gcc_assert, get_odr_type(), inform(), symtab_node::iterate_reference(), methods_equal_p(), odr_type_d::odr_violated, odr_violation_reported, polymorphic_type_binfo_p(), ipa_ref::referred, ipa_ref::referring, odr_type_d::rtti_broken, TREE_CODE, TYPE_BINFO, TYPE_NAME, symtab_node::ultimate_alias_target(), VAR_P, and warning_at().
|
static |
If T is compound type, return type it is based on.
References NULL_TREE, POINTER_TYPE_P, TREE_CODE, TREE_TYPE, TYPE_METHOD_BASETYPE, TYPE_OFFSET_BASETYPE, and VECTOR_TYPE_P.
Referenced by odr_or_derived_type_p().
DEBUG_FUNCTION void debug_tree_odr_name | ( | tree | type, |
bool | demangle ) |
Print ODR name of a TYPE if available. Use demangler when option DEMANGLE is used.
References get_odr_name_for_type().
|
static |
Compare decl warning records P1 and P2 and choose one with larger count; helper for qsort.
References decl_warn_count::count, and decl_warn_count::dyn_count.
Referenced by ipa_devirt().
|
static |
When virtual function is removed, we may need to flush the cache.
References cached_polymorphic_call_targets, free_polymorphic_call_targets_hash(), and thunk_expansion.
Referenced by possible_polymorphic_call_targets().
|
static |
When virtual table is removed, we may need to flush the cache.
References cached_polymorphic_call_targets, symtab_node::decl, DECL_CONTEXT, DECL_VIRTUAL_P, free_polymorphic_call_targets_hash(), and type_in_anonymous_namespace_p().
Referenced by possible_polymorphic_call_targets().
|
static |
Dump ODR type T and all its derived types. INDENT specifies indentation for recursive printing.
References odr_type_d::all_derivations_known, odr_type_d::anonymous_namespace, odr_type_d::bases, DECL_ASSEMBLER_NAME, DECL_ASSEMBLER_NAME_SET_P, odr_type_d::derived_types, dump_odr_type(), i, odr_type_d::id, IDENTIFIER_POINTER, print_generic_expr(), TDF_SLIM, odr_type_d::type, and TYPE_NAME.
Referenced by dump_odr_type(), and dump_type_inheritance_graph().
void dump_possible_polymorphic_call_targets | ( | FILE * | f, |
tree | otr_type, | ||
HOST_WIDE_INT | otr_token, | ||
const ipa_polymorphic_call_context & | ctx, | ||
bool | verbose ) |
Dump all possible targets of a polymorphic call.
References ipa_polymorphic_call_context::dump(), dump_targets(), gcc_assert, get_odr_type(), IPA_SSA, ipa_polymorphic_call_context::maybe_derived_type, ipa_polymorphic_call_context::maybe_in_construction, NULL, possible_polymorphic_call_targets(), print_generic_expr(), ipa_polymorphic_call_context::speculative_maybe_derived_type, symbol_table::state, symtab, TDF_SLIM, TYPE_MAIN_VARIANT, and verbose.
Referenced by dump_possible_polymorphic_call_targets(), eliminate_dom_walker::eliminate_stmt(), ipa_devirt(), and walk_polymorphic_call_targets().
|
static |
Dump target list TARGETS into FILE.
References DECL_DECLARED_INLINE_P, free(), i, NULL, and verbose.
Referenced by dump_possible_polymorphic_call_targets().
|
static |
Dump the type inheritance graph.
References COMPLETE_TYPE_P, dump_odr_type(), i, odr_types, odr_types_ptr, print_node(), TREE_CODE, TYPE_CONTEXT, TYPE_NAME, and TYPE_P.
Referenced by build_type_inheritance_graph(), and ipa_devirt().
void enable_odr_based_tbaa | ( | tree | type | ) |
Set tbaa_enabled flag for TYPE.
References get_odr_type(), and odr_type_d::tbaa_enabled.
|
static |
Save some WPA->ltrans streaming by freeing stuff needed only for good ODR warnings. We make TYPE_DECLs to not point back to the type (which is needed to keep them in the same SCC and preserve location information to output warnings) and subsequently we make all TYPE_DECLS of same assembler name equivalent.
References i, odr_types, odr_types_ptr, TREE_TYPE, TYPE_NAME, and void_type_node.
Referenced by build_type_inheritance_graph().
|
static |
Destroy polymorphic call target query cache.
References cached_polymorphic_call_targets, NULL, and polymorphic_call_target_hash.
Referenced by devirt_node_removal_hook(), devirt_variable_node_removal_hook(), ipa_devirt(), rebuild_type_inheritance_graph(), and update_type_inheritance_graph().
Get ODR type hash entry for TYPE. If INSERT is true, create possibly new entry.
References hash_set< KeyId, Lazy, Traits >::add(), add_type_duplicate(), odr_type_d::all_derivations_known, odr_type_d::anonymous_namespace, odr_type_d::bases, BINFO_BASE_BINFO, BINFO_N_BASE_BINFOS, BINFO_TYPE, can_be_name_hashed_p(), COMPLETE_TYPE_P, odr_type_d::derived_types, hash_table< Descriptor, Lazy, Allocator >::find_slot_with_hash(), gcc_assert, gcc_checking_assert, get_odr_type(), ggc_cleared_alloc(), hash_odr_name(), i, odr_type_d::id, insert(), NULL, odr_hash, odr_types, odr_types_ptr, polymorphic_type_binfo_p(), TREE_CODE, odr_type_d::type, type(), type_all_derivations_known_p(), TYPE_BINFO, TYPE_CANONICAL, type_in_anonymous_namespace_p(), TYPE_MAIN_VARIANT, TYPE_STRUCTURAL_EQUALITY_P, type_with_linkage_p(), odr_type_d::types_set, vec_safe_push(), and vNULL.
Referenced by add_type_duplicate(), build_type_inheritance_graph(), compare_virtual_tables(), dump_possible_polymorphic_call_targets(), enable_odr_based_tbaa(), get_odr_type(), obj_type_ref_class(), odr_based_tbaa_p(), odr_subtypes_equivalent_p(), odr_type_violation_reported_p(), possible_polymorphic_call_targets(), prevailing_odr_type(), register_odr_type(), set_type_canonical_for_odr_type(), type_known_to_have_no_derivations_p(), and update_type_inheritance_graph().
|
static |
Hash type by its ODR name.
References DECL_ASSEMBLER_NAME, DECL_ASSEMBLER_NAME_SET_P, gcc_checking_assert, IDENTIFIER_HASH_VALUE, type_in_anonymous_namespace_p(), TYPE_MAIN_VARIANT, TYPE_NAME, and type_with_linkage_p().
Referenced by get_odr_type(), and odr_name_hasher::hash().
|
static |
The ipa-devirt pass. When polymorphic call has only one likely target in the unit, turn it into a speculative call.
References hash_set< KeyId, Lazy, Traits >::add(), add_decl_warning(), symtab_node::alias, profile_count::apply_scale(), AVAIL_INTERPOSABLE, cgraph_edge::call_stmt, symtab_node::can_be_discarded_p(), hash_set< KeyId, Lazy, Traits >::contains(), cgraph_edge::count, count, dbg_cnt(), symtab_node::decl, DECL_ARTIFICIAL, DECL_CONTEXT, DECL_CXX_DESTRUCTOR_P, DECL_EXTERNAL, DECL_SOURCE_LOCATION, decl_warning_cmp(), final_warning_record::decl_warnings, symtab_node::definition, dump_enabled_p(), dump_file, dump_flags, symtab_node::dump_name(), dump_possible_polymorphic_call_targets(), dump_printf_loc(), dump_type_inheritance_graph(), dyn_cast(), final_warning_record::dyn_count, final_warning_records, FOR_EACH_DEFINED_FUNCTION, free_polymorphic_call_targets_hash(), cgraph_node::function_symbol(), cgraph_node::get_availability(), final_warning_record::grow_type_warnings(), i, cgraph_node::indirect_calls, cgraph_edge::indirect_info, profile_count::ipa(), ipa_update_overall_fn_summary(), likely_target_p(), cgraph_edge::make_speculative(), cgraph_edge::maybe_hot_p(), MSG_OPTIMIZED_LOCATIONS, cgraph_edge::next_callee, symtab_node::noninterposable_alias(), NULL, odr_types, odr_types_ptr, opt_for_fn, cgraph_indirect_call_info::param_index, cgraph_indirect_call_info::polymorphic, possible_polymorphic_call_targets(), cgraph_edge::speculative, cgraph_edge::speculative_call_for_target(), TDF_DETAILS, profile_count::to_gcov_type(), TODO_remove_functions, hash_map< KeyId, Value, Traits >::traverse(), TYPE_NAME, type_warning_cmp(), final_warning_record::type_warnings, cgraph_indirect_call_info::vptr_changed, warning_n(), and profile_count::zero().
|
static |
Write ODR enums from LTO stream file and warn on mismatches.
References lto_location_cache::apply_location_cache(), dump_file, data_in::file_data, wi::fits_shwi_p(), free(), gcc_obstack_init, wide_int_storage::get_precision(), header, HOST_WIDE_INT_PRINT_DEC, i, inform(), data_in::location_cache, odr_enum::locus, lto_data_in_create(), lto_data_in_delete(), lto_free_section_data(), LTO_section_ipa_fn_summary, NULL, odr_enum_map, odr_enum_obstack, lto_location_cache::revert_location_cache(), stream_input_location, streamer_read_bitpack(), streamer_read_string(), streamer_read_uhwi(), streamer_read_wide_int(), generic_wide_int< storage >::to_shwi(), odr_enum::vals, vNULL, odr_enum::warned, warning_at(), and wi::zero().
Referenced by ipa_odr_summary_read().
|
static |
Read all ODR type sections.
References INCREMENTAL_LINK_LTO, ipa_odr_read_section(), lto_get_file_decl_data(), lto_get_summary_section_data(), LTO_section_odr_types, NULL, odr_enum_map, and odr_enum_obstack.
|
static |
Write ODR enums to LTO stream file.
References bitpack_create(), create_output_block(), DECL_ASSEMBLER_NAME, DECL_INITIAL, DECL_SOURCE_LOCATION, destroy_output_block(), FOR_EACH_VEC_ELT, gcc_checking_assert, i, IDENTIFIER_POINTER, odr_enum::locus, lto_output_location(), LTO_section_odr_types, output_block::main_stream, NULL, odr_enum_map, odr_enum_obstack, odr_enums, produce_asm(), streamer_write_bitpack(), streamer_write_string(), streamer_write_uhwi(), streamer_write_wide_int(), wi::to_wide(), TREE_CHAIN, TREE_PURPOSE, TREE_VALUE, TYPE_NAME, TYPE_VALUES, odr_enum::vals, and vec_free().
Return if TARGET is cxa_pure_virtual.
References DECL_NAME, id_equal(), TREE_CODE, and TREE_TYPE.
Referenced by maybe_record_node(), and possible_polymorphic_call_target_p().
bool likely_target_p | ( | struct cgraph_node * | n | ) |
Return true if N looks like likely target of a polymorphic call. Rule out cxa_pure_virtual, noreturns, function declared cold and other obvious cases.
References symtab_node::decl, DECL_ATTRIBUTES, ECF_NORETURN, flags_from_decl_or_type(), cgraph_node::frequency, lookup_attribute(), NODE_FREQUENCY_NORMAL, referenced_from_vtable_p(), TREE_CODE, and TREE_TYPE.
Referenced by ipa_devirt(), and try_speculative_devirtualization().
ipa_opt_pass_d * make_pass_ipa_devirt | ( | gcc::context * | ctxt | ) |
ipa_opt_pass_d * make_pass_ipa_odr | ( | gcc::context * | ctxt | ) |
|
static |
If TARGET has associated node, record it in the NODES array. CAN_REFER specify if program can refer to the target directly. if TARGET is unknown (NULL) or it cannot be inserted (for example because its body was already removed and there is no way to refer to it), clear COMPLETEP.
References hash_set< KeyId, Lazy, Traits >::add(), symtab_node::alias_target, AVAIL_AVAILABLE, cached_polymorphic_call_targets, DECL_CONTEXT, DECL_EXTERNAL, symtab_node::definition, gcc_assert, cgraph_node::get(), cgraph_node::get_availability(), cgraph_node::inlined_to, is_cxa_pure_virtual_p(), NULL, symtab_node::real_symbol_p(), referenced_from_vtable_p(), SANITIZE_UNREACHABLE, TREE_CODE, TREE_PUBLIC, TREE_TYPE, type_in_anonymous_namespace_p(), and cgraph_node::ultimate_alias_target().
Referenced by possible_polymorphic_call_targets(), record_target_from_binfo(), and record_targets_from_bases().
Return true if DECL1 and DECL2 are identical methods. Consider name equivalent to name.localalias.xyz.
References DECL_ASSEMBLER_NAME, IDENTIFIER_POINTER, and symbol_table::symbol_suffix_separator().
Referenced by compare_virtual_tables().
tree obj_type_ref_class | ( | const_tree | ref, |
bool | for_dump_p ) |
REF is OBJ_TYPE_REF, return the class the ref corresponds to. FOR_DUMP_P is true when being called from the dump routines.
References gcc_assert, gcc_checking_assert, get_odr_type(), TREE_CODE, TREE_TYPE, TREE_VALUE, TYPE_ARG_TYPES, TYPE_CANONICAL, and TYPE_STRUCTURAL_EQUALITY_P.
Referenced by cgraph_node::create_indirect_edge(), dump_generic_node(), eliminate_dom_walker::eliminate_stmt(), operand_compare::hash_operand(), ipa_analyze_call_uses(), ipa_analyze_virtual_call_uses(), ipa_polymorphic_call_context::ipa_polymorphic_call_context(), operand_compare::operand_equal_p(), possible_polymorphic_call_target_p(), possible_polymorphic_call_targets(), and virtual_method_call_p().
bool odr_based_tbaa_p | ( | const_tree | type | ) |
True if canonical type of TYPE is determined using ODR name.
References get_odr_type(), odr_hash, RECORD_OR_UNION_TYPE_P, and odr_type_d::tbaa_enabled.
Referenced by gimple_canonical_types_compatible_p(), and record_component_aliases().
bool odr_or_derived_type_p | ( | const_tree | t | ) |
Return true if T is either ODR type or compound type based from it. If the function return true, we know that T is a type originating from C++ source even at link-time.
References compound_type_base(), odr_or_derived_type_p(), odr_type_p(), TREE_CHAIN, TREE_CODE, TREE_TYPE, TREE_VALUE, TYPE_ARG_TYPES, TYPE_MAIN_VARIANT, and TYPE_METHOD_BASETYPE.
Referenced by odr_or_derived_type_p(), odr_types_equivalent_p(), and type_mismatch_p().
|
static |
Compare T1 and T2 based on name or structure.
References AGGREGATE_TYPE_P, gcc_assert, get_odr_type(), NULL, NULL_TREE, odr_type_p(), odr_types_equivalent_p(), TREE_CODE, type_in_anonymous_namespace_p(), TYPE_MAIN_VARIANT, TYPE_NAME, TYPE_UID, type_variants_equivalent_p(), type_with_linkage_p(), types_odr_comparable(), types_same_for_odr(), and visited.
Referenced by odr_types_equivalent_p().
Return true if we reported some ODR violation on TYPE.
References get_odr_type(), and odr_type_d::odr_violated.
Return true if TYPE1 and TYPE2 are equivalent for One Definition Rule.
References gcc_checking_assert, NULL, odr_or_derived_type_p(), odr_types_equivalent_p(), UNKNOWN_LOCATION, and visited.
|
static |
Compare T1 and T2, report ODR violations if WARN is true and set WARNED to true if anything is reported. Return true if types match. If true is returned, the types are also compatible in the sense of gimple_canonical_types_compatible_p. If LOC1 and LOC2 is not UNKNOWN_LOCATION it may be used to output a warning about the type if the type itself do not have location.
References COMPLETE_TYPE_P, debug_tree(), DECL_ARTIFICIAL, DECL_BIT_FIELD, DECL_NAME, DECL_NONADDRESSABLE_P, DECL_VIRTUAL_P, f1, f2, FIXED_POINT_TYPE_P, G_, gcc_assert, gcc_checking_assert, gcc_unreachable, gimple_compare_field_offset(), i1, i2, INTEGRAL_TYPE_P, NULL, NULL_TREE, odr_subtypes_equivalent_p(), operand_equal_p(), POINTER_TYPE_P, polymorphic_type_binfo_p(), prototype_p(), RECORD_OR_UNION_TYPE_P, SCALAR_FLOAT_TYPE_P, skip_in_fields_list_p(), TREE_ADDRESSABLE, TREE_CHAIN, TREE_CODE, TREE_TYPE, TREE_VALUE, TYPE_ADDR_SPACE, TYPE_ARG_TYPES, TYPE_BINFO, TYPE_DOMAIN, TYPE_FIELDS, type_in_anonymous_namespace_p(), TYPE_MAIN_VARIANT, TYPE_MAX_VALUE, TYPE_MIN_VALUE, TYPE_MODE, TYPE_NONALIASED_COMPONENT, TYPE_PRECISION, TYPE_SIZE, TYPE_SIZE_UNIT, TYPE_STRING_FLAG, TYPE_UNSIGNED, type_variants_equivalent_p(), type_with_linkage_p(), VECTOR_TYPE_P, visited, warn_odr(), and warn_types_mismatch().
Referenced by add_type_duplicate(), odr_subtypes_equivalent_p(), odr_types_equivalent_p(), and type_mismatch_p().
bool possible_polymorphic_call_target_p | ( | tree | otr_type, |
HOST_WIDE_INT | otr_token, | ||
const ipa_polymorphic_call_context & | ctx, | ||
struct cgraph_node * | n ) |
Return true if N can be possibly target of a polymorphic call of OTR_TYPE/OTR_TOKEN.
References BUILT_IN_NORMAL, symtab_node::decl, DECL_FUNCTION_CODE(), symtab_node::definition, fndecl_built_in_p(), i, is_cxa_pure_virtual_p(), odr_hash, possible_polymorphic_call_targets(), and symtab_node::semantically_equivalent_p().
Referenced by gimple_fold_call(), ipa_get_indirect_edge_target_1(), ipa_profile(), possible_polymorphic_call_target_p(), and try_make_edge_direct_virtual_call().
bool possible_polymorphic_call_target_p | ( | tree | ref, |
gimple * | stmt, | ||
struct cgraph_node * | n ) |
Return true if N can be possibly target of a polymorphic call of OBJ_TYPE_REF expression REF in STMT.
References current_function_decl, gimple_call_fn(), obj_type_ref_class(), OBJ_TYPE_REF_TOKEN, possible_polymorphic_call_target_p(), and tree_to_uhwi().
Referenced by possible_polymorphic_call_target_p().
vec< cgraph_node * > possible_polymorphic_call_targets | ( | tree | otr_type, |
HOST_WIDE_INT | otr_token, | ||
ipa_polymorphic_call_context | context, | ||
bool * | completep, | ||
void ** | cache_token, | ||
bool | speculative ) |
Return vector containing possible targets of polymorphic call of type OTR_TYPE calling method OTR_TOKEN within type of OTR_OUTER_TYPE and OFFSET. If INCLUDE_BASES is true, walk also base types of OUTER_TYPES containing OTR_TYPE and include their virtual method. This is useful for types possibly in construction or destruction where the virtual table may temporarily change to one of base types. INCLUDE_DERIVED_TYPES make us to walk the inheritance graph for all derivations. If COMPLETEP is non-NULL, store true if the list is complete. CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry in the target cache. If user needs to visit every target list just once, it can memoize them. If SPECULATIVE is set, the list will not contain targets that are not speculatively taken. Returned vector is placed into cache. It is NOT caller's responsibility to free it. The vector can be freed on cgraph_remove_node call if the particular node is a virtual function present in the cache.
References hash_set< KeyId, Lazy, Traits >::add(), symbol_table::add_cgraph_removal_hook(), symbol_table::add_varpool_removal_hook(), odr_type_d::all_derivations_known, BINFO_VTABLE, cached_polymorphic_call_targets, ipa_polymorphic_call_context::clear_outer_type(), ipa_polymorphic_call_context::clear_speculation(), polymorphic_call_target_d::context, decl_warn_count::count, decl_warn_count::decl, DECL_CONTEXT, DECL_CXX_DESTRUCTOR_P, DECL_FINAL_P, final_warning_record::decl_warnings, odr_type_d::derived_types, devirt_node_removal_hook(), devirt_variable_node_removal_hook(), decl_warn_count::dyn_count, final_warning_record::dyn_count, final_warning_records, hash_table< Descriptor, Lazy, Allocator >::find_slot(), gcc_assert, hash_map< KeyId, Value, Traits >::get(), get_binfo_at_offset(), get_odr_type(), hash_map< KeyId, Value, Traits >::get_or_insert(), gimple_get_virt_method_for_binfo(), final_warning_record::grow_type_warnings(), i, odr_type_d::id, ipa_polymorphic_call_context::invalid, ipa_polymorphic_call_context::maybe_derived_type, ipa_polymorphic_call_context::maybe_in_construction, maybe_record_node(), MIN, polymorphic_call_target_d::n_odr_types, NULL, odr_hash, odr_types, odr_violation_reported, ipa_polymorphic_call_context::offset, polymorphic_call_target_d::otr_token, ipa_polymorphic_call_context::outer_type, polymorphic_call_target_hash, possible_polymorphic_call_targets_1(), record_targets_from_bases(), ipa_polymorphic_call_context::restrict_to_inner_class(), polymorphic_call_target_d::speculative, ipa_polymorphic_call_context::speculative_maybe_derived_type, ipa_polymorphic_call_context::speculative_offset, ipa_polymorphic_call_context::speculative_outer_type, symtab, timevar_pop(), timevar_push(), TREE_CODE, TREE_TYPE, odr_type_d::type, polymorphic_call_target_d::type, type(), type_all_derivations_known_p(), TYPE_BINFO, TYPE_FINAL_P, TYPE_MAIN_VARIANT, type_or_derived_type_possibly_instantiated_p(), type_possibly_instantiated_p(), final_warning_record::type_warnings, types_same_for_odr(), vNULL, and profile_count::zero().
Referenced by compute_ltrans_boundary(), dump_possible_polymorphic_call_targets(), eliminate_dom_walker::eliminate_stmt(), fold_gimple_assign(), gimple_fold_call(), ipa_devirt(), ipa_get_indirect_edge_target_1(), possible_polymorphic_call_target_p(), possible_polymorphic_call_targets(), possible_polymorphic_call_targets(), try_make_edge_direct_virtual_call(), try_speculative_devirtualization(), walk_polymorphic_call_targets(), and walk_polymorphic_call_targets().
|
static |
Look up virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN) of TYPE, insert them to NODES, recurse into derived nodes. INSERTED is used to avoid duplicate insertions of methods into NODES. MATCHED_VTABLES are used to avoid duplicate walking vtables. Clear COMPLETEP if unreferable target is found. If CONSIDER_CONSTRUCTION is true, record to BASES_TO_CONSIDER all cases where BASE_SKIPPED is true (because the base is abstract class).
References i, NULL, offset, possible_polymorphic_call_targets_1(), record_target_from_binfo(), type_all_derivations_known_p(), TYPE_BINFO, and type_possibly_instantiated_p().
Referenced by possible_polymorphic_call_targets(), and possible_polymorphic_call_targets_1().
Return type that in ODR type hash prevailed TYPE. Be careful and punt on ODR violations.
References get_odr_type(), odr_type_d::odr_violated, odr_type_d::type, and type().
Referenced by get_alias_set().
void rebuild_type_inheritance_graph | ( | void | ) |
Force rebuilding type inheritance graph from scratch. This is use to make sure that we do not keep references to types which was not visible to free_lang_data.
References free_polymorphic_call_targets_hash(), NULL, odr_hash, and odr_types_ptr.
|
static |
See if BINFO's type matches OUTER_TYPE. If so, look up BINFO of subtype of OTR_TYPE at OFFSET and in that BINFO find method in vtable and insert method to NODES array or BASES_TO_CONSIDER if this array is non-NULL. Otherwise recurse to base BINFOs. This matches what get_binfo_at_offset does, but with offset being unknown. TYPE_BINFOS is a stack of BINFOS of types with defined virtual table seen on way from class type to BINFO. MATCHED_VTABLES tracks virtual tables we already did lookup for virtual function in. INSERTED tracks nodes we already inserted. ANONYMOUS is true if BINFO is part of anonymous namespace. Clear COMPLETEP when we hit unreferable target.
References hash_set< KeyId, Lazy, Traits >::add(), BINFO_BASE_ITERATE, BINFO_OFFSET, BINFO_TYPE, BINFO_VTABLE, hash_set< KeyId, Lazy, Traits >::contains(), DECL_CXX_DESTRUCTOR_P, symtab_node::definition, gcc_assert, varpool_node::get(), get_binfo_at_offset(), gimple_get_virt_method_for_binfo(), i, maybe_record_node(), NULL, odr_violation_reported, offset, polymorphic_type_binfo_p(), record_target_from_binfo(), TREE_CODE, TREE_OPERAND, and types_same_for_odr().
Referenced by possible_polymorphic_call_targets_1(), and record_target_from_binfo().
|
static |
Walk bases of OUTER_TYPE that contain OTR_TYPE at OFFSET. Look up their respective virtual methods for OTR_TOKEN and OTR_TYPE and insert them in NODES. MATCHED_VTABLES and INSERTED is used to avoid duplicated work.
References hash_set< KeyId, Lazy, Traits >::add(), BINFO_VTABLE, DECL_ARTIFICIAL, DECL_CHAIN, DECL_CXX_DESTRUCTOR_P, DECL_SIZE, gcc_assert, get_binfo_at_offset(), gimple_get_virt_method_for_binfo(), int_bit_position(), maybe_record_node(), odr_violation_reported, offset, polymorphic_type_binfo_p(), TREE_CODE, tree_to_shwi(), TREE_TYPE, TYPE_BINFO, TYPE_FIELDS, and types_same_for_odr().
Referenced by possible_polymorphic_call_targets().
|
static |
Return true if N has reference from live virtual table (and thus can be a destination of polymorphic call). Be conservatively correct when callgraph is not built or if the method may be referred externally.
References CONSTRUCTION, symtab_node::decl, DECL_EXTERNAL, DECL_VIRTUAL_P, dyn_cast(), symtab_node::externally_visible, i, IPA_REF_ADDR, IPA_REF_ALIAS, symtab_node::iterate_referring(), symtab_node::ref_list, referenced_from_vtable_p(), ipa_ref::referring, ipa_ref_list::referring, symbol_table::state, symtab, ipa_ref::use, symtab_node::used_from_other_partition, and VAR_P.
Referenced by likely_target_p(), maybe_record_node(), and referenced_from_vtable_p().
void register_odr_enum | ( | tree | t | ) |
Register ODR enum so we later stream record about its values.
References odr_enums, and vec_safe_push().
void register_odr_type | ( | tree | type | ) |
Add TYPE of ODR type hash.
References BINFO_BASE_BINFO, BINFO_N_BASE_BINFOS, BINFO_TYPE, COMPLETE_TYPE_P, hash_set< KeyId, Lazy, Traits >::contains(), get_odr_type(), i, odr_hash, RECORD_OR_UNION_TYPE_P, register_odr_type(), TREE_CHAIN, TREE_CODE, TREE_TYPE, odr_type_d::type, TYPE_BINFO, TYPE_FIELDS, TYPE_MAIN_VARIANT, type_with_linkage_p(), and odr_type_d::types_set.
Referenced by register_odr_type().
Set TYPE_BINFO of TYPE and its variants to BINFO.
References COMPLETE_TYPE_P, gcc_assert, type(), TYPE_BINFO, and TYPE_NEXT_VARIANT.
Referenced by add_type_duplicate().
Set TYPE_CANONICAL of type and all its variants and duplicates to CANONICAL.
References FOR_EACH_VEC_ELT, get_odr_type(), i, odr_type_d::type, TYPE_CANONICAL, TYPE_NEXT_VARIANT, and odr_type_d::types.
Return true if T should be ignored in TYPE_FIELDS for ODR comparison.
References DECL_ARTIFICIAL, DECL_IGNORED_P, DECL_NAME, DECL_SIZE, integer_zerop(), and TREE_CODE.
Referenced by odr_types_equivalent_p().
Look up base of BINFO that has virtual table VTABLE with OFFSET.
References BINFO_BASE_ITERATE, BINFO_VTABLE, DECL_ASSEMBLER_NAME, gcc_unreachable, i, NULL, offset, polymorphic_type_binfo_p(), subbinfo_with_vtable_at_offset(), and vtable_pointer_value_to_vtable().
Referenced by extr_type_from_vtbl_ptr_store(), subbinfo_with_vtable_at_offset(), and vtable_pointer_value_to_binfo().
struct cgraph_node * try_speculative_devirtualization | ( | tree | otr_type, |
HOST_WIDE_INT | otr_token, | ||
ipa_polymorphic_call_context | ctx ) |
Try to speculatively devirtualize call to OTR_TYPE with OTR_TOKEN with context CTX.
References AVAIL_INTERPOSABLE, symtab_node::can_be_discarded_p(), symtab_node::decl, DECL_ARTIFICIAL, DECL_EXTERNAL, symtab_node::definition, cgraph_node::function_symbol(), cgraph_node::get_availability(), i, likely_target_p(), NULL, and possible_polymorphic_call_targets().
Referenced by ipa_get_indirect_edge_target_1(), and try_make_edge_direct_virtual_call().
Return TRUE if type's constructors are all visible.
References CONSTRUCTION, symbol_table::state, symtab, and type_in_anonymous_namespace_p().
Referenced by type_possibly_instantiated_p().
bool type_all_derivations_known_p | ( | const_tree | t | ) |
Return TRUE if all derived types of T are known and thus we may consider the walk of derived type complete. This is typically true only for final anonymous namespace types and types defined within functions (that may be COMDAT and thus shared across units, but with the same set of derived types).
References decl_function_context(), NULL, TREE_CODE, TYPE_FINAL_P, type_in_anonymous_namespace_p(), and TYPE_NAME.
Referenced by get_odr_type(), possible_polymorphic_call_targets(), possible_polymorphic_call_targets_1(), and type_known_to_have_no_derivations_p().
Return true if type is known to have no derivations.
References get_odr_type(), odr_hash, type_all_derivations_known_p(), and TYPE_FINAL_P.
Referenced by ipa_polymorphic_call_context::restrict_to_inner_class().
Return true if T1 and T2 are incompatible and we want to recursively dive into them from warn_type_mismatch to give sensible answer.
References odr_or_derived_type_p(), odr_types_equivalent_p(), and types_compatible_p().
Referenced by warn_types_mismatch().
Return true if T or type derived from T may have instance.
References odr_type_d::derived_types, odr_type_d::type, type_or_derived_type_possibly_instantiated_p(), and type_possibly_instantiated_p().
Referenced by possible_polymorphic_call_targets(), and type_or_derived_type_possibly_instantiated_p().
Return TRUE if type may have instance.
References BINFO_VTABLE, symtab_node::definition, varpool_node::get(), TREE_CODE, TREE_OPERAND, type_all_ctors_visible_p(), and TYPE_BINFO.
Referenced by possible_polymorphic_call_targets(), possible_polymorphic_call_targets_1(), and type_or_derived_type_possibly_instantiated_p().
Return true if type variants match. This assumes that we already verified that T1 and T2 are variants of the same type.
References comp_type_attributes(), COMPLETE_TYPE_P, TYPE_ALIGN, and TYPE_QUALS.
Referenced by odr_subtypes_equivalent_p(), and odr_types_equivalent_p().
|
static |
Compare type warning records P1 and P2 and choose one with larger count; helper for qsort.
References odr_type_warn_count::count, and odr_type_warn_count::dyn_count.
Referenced by ipa_devirt().
Return true if T1 and T2 are ODR equivalent. If ODR equivalency is not known, be conservative and return false.
References TYPE_MAIN_VARIANT, types_odr_comparable(), and types_same_for_odr().
Referenced by ipa_polymorphic_call_context::combine_speculation_with(), ipa_polymorphic_call_context::combine_with(), ipa_icf::sem_item::compare_referenced_symbol_properties(), ipa_icf_gimple::func_checker::compatible_polymorphic_types_p(), ipa_polymorphic_call_context::meet_speculation_with(), ipa_polymorphic_call_context::meet_with(), ipa_polymorphic_call_context::restrict_to_inner_class(), and ipa_polymorphic_call_context::speculation_consistent_p().
Return true if we can decide on ODR equivalency. In non-LTO it is always decide, in LTO however it depends in the type has ODR info attached.
References odr_type_p(), and TYPE_MAIN_VARIANT.
Referenced by add_type_duplicate(), ipa_polymorphic_call_context::combine_with(), decl_maybe_in_construction_p(), ipa_polymorphic_call_context::equal_to(), odr_subtypes_equivalent_p(), ipa_polymorphic_call_context::restrict_to_inner_class(), types_must_be_same_for_odr(), and warn_types_mismatch().
bool types_same_for_odr | ( | const_tree | type1, |
const_tree | type2 ) |
For languages with One Definition Rule, work out if types are the same based on their name. This is non-trivial for LTO where minor differences in the type representation may have prevented type merging to merge two copies of otherwise equivalent type. Until we start streaming mangled type names, this function works only for polymorphic types.
References DECL_ASSEMBLER_NAME, gcc_checking_assert, type_in_anonymous_namespace_p(), TYPE_MAIN_VARIANT, TYPE_NAME, TYPE_P, and type_with_linkage_p().
Referenced by add_type_duplicate(), decl_maybe_in_construction_p(), ipa_polymorphic_call_context::equal_to(), get_binfo_at_offset(), ipa_polymorphic_call_context::get_dynamic_type(), lookup_binfo_at_offset(), odr_subtypes_equivalent_p(), operand_compare::operand_equal_p(), possible_polymorphic_call_targets(), record_known_type(), record_target_from_binfo(), record_targets_from_bases(), ipa_polymorphic_call_context::restrict_to_inner_class(), types_must_be_same_for_odr(), and warn_types_mismatch().
void update_type_inheritance_graph | ( | void | ) |
After callgraph construction new external nodes may appear. Add them into the graph.
References symtab_node::decl, DECL_VIRTUAL_P, symtab_node::definition, FOR_EACH_FUNCTION, free_polymorphic_call_targets_hash(), get_odr_type(), odr_hash, symtab_node::real_symbol_p(), timevar_pop(), timevar_push(), TREE_TYPE, and TYPE_METHOD_BASETYPE.
Referenced by analyze_functions().
tree vtable_pointer_value_to_binfo | ( | const_tree | t | ) |
T is known constant value of virtual table pointer. Return BINFO of the instance type.
References DECL_CONTEXT, NULL_TREE, offset, subbinfo_with_vtable_at_offset(), TYPE_BINFO, and vtable_pointer_value_to_vtable().
bool vtable_pointer_value_to_vtable | ( | const_tree | t, |
tree * | v, | ||
unsigned HOST_WIDE_INT * | offset ) |
T is known constant value of virtual table pointer. Store virtual table to V and its offset to OFFSET. Return false if T does not look like virtual table reference.
References DECL_VIRTUAL_P, offset, TREE_CODE, TREE_OPERAND, and tree_to_uhwi().
Referenced by extr_type_from_vtbl_ptr_store(), gimple_get_virt_method_for_binfo(), ipa_get_indirect_edge_target_1(), subbinfo_with_vtable_at_offset(), try_make_edge_direct_virtual_call(), and vtable_pointer_value_to_binfo().
|
static |
Output ODR violation warning about T1 and T2 with REASON. Display location of ST1 and ST2 if REASON speaks about field or method of the type. If WARN is false, do nothing. Set WARNED if warning was indeed output.
References lto_location_cache::apply_location_cache(), lto_location_cache::current_cache, DECL_SOURCE_LOCATION, inform(), NULL, TREE_CODE, TYPE_MAIN_VARIANT, TYPE_NAME, and warning_at().
Referenced by add_type_duplicate(), and odr_types_equivalent_p().
Types T1 and T2 was found to be incompatible in a context they can't (either used to declare a symbol of same assembler name or unified by ODR rule). We already output warning about this, but if possible, output extra information on how the types mismatch. This is hard to do in general. We basically handle the common cases. If LOC1 and LOC2 are meaningful locations, use it in the case the types themselves do not have one.
References BUILTINS_LOCATION, COMPLETE_TYPE_P, count, DECL_NAME, DECL_SOURCE_LOCATION, expand_location(), free(), gcc_assert, get_odr_name_for_type(), i1, i2, inform(), NULL, operand_equal_p(), POINTER_TYPE_P, prototype_p(), TREE_CHAIN, TREE_CODE, TREE_TYPE, TREE_VALUE, TYPE_ARG_TYPES, TYPE_DOMAIN, type_in_anonymous_namespace_p(), TYPE_MAIN_VARIANT, TYPE_MAX_VALUE, type_mismatch_p(), TYPE_NAME, type_with_linkage_p(), types_odr_comparable(), types_same_for_odr(), UNKNOWN_LOCATION, and warn_types_mismatch().
Referenced by add_type_duplicate(), odr_types_equivalent_p(), and warn_types_mismatch().
|
static |
Pointer set of all call targets appearing in the cache.
Referenced by devirt_node_removal_hook(), devirt_variable_node_removal_hook(), free_polymorphic_call_targets_hash(), maybe_record_node(), and possible_polymorphic_call_targets().
class final_warning_record* final_warning_records |
Referenced by ipa_devirt(), and possible_polymorphic_call_targets().
|
static |
A table of all ODR enum definitions.
Referenced by ipa_odr_read_section(), ipa_odr_summary_read(), and ipa_odr_summary_write().
|
static |
Referenced by ipa_odr_read_section(), ipa_odr_summary_read(), and ipa_odr_summary_write().
All enums defined and accessible for the unit.
Referenced by ipa_odr_summary_write(), and register_odr_enum().
|
static |
Referenced by add_type_duplicate(), build_type_inheritance_graph(), get_odr_type(), odr_based_tbaa_p(), possible_polymorphic_call_target_p(), possible_polymorphic_call_targets(), rebuild_type_inheritance_graph(), register_odr_type(), type_known_to_have_no_derivations_p(), and update_type_inheritance_graph().
ODR types are also stored into ODR_TYPE vector to allow consistent walking. Bases appear before derived types. Vector is garbage collected so we won't end up visiting empty types.
Referenced by dump_type_inheritance_graph(), free_odr_warning_data(), get_odr_type(), ipa_devirt(), and rebuild_type_inheritance_graph().
|
static |
Referenced by free_polymorphic_call_targets_hash(), and possible_polymorphic_call_targets().
bool thunk_expansion |
HACK alert: this is used to communicate with ipa-inline-transform that thunk is being expanded and there is no need to clear the polymorphic call target cache.
Referenced by devirt_node_removal_hook(), and inline_call().