GCC Middle and Back End API Reference
ipa-devirt.cc File 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"
Include dependency graph for ipa-devirt.cc:

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


#define odr_types   (*odr_types_ptr)


typedef hash_table< odr_name_hasherodr_hash_type
typedef hash_table< polymorphic_call_target_hasherpolymorphic_call_target_hash_type


static bool odr_types_equivalent_p (tree, tree, bool, bool *, hash_set< type_pair > *, location_t, location_t)
static void warn_odr (tree t1, tree t2, tree st1, tree st2, bool warn, bool *warned, const char *reason)
bool type_all_derivations_known_p (const_tree t)
static bool type_all_ctors_visible_p (tree t)
static bool type_possibly_instantiated_p (tree t)
static bool type_or_derived_type_possibly_instantiated_p (odr_type t)
static bool can_be_name_hashed_p (tree t)
static hashval_t hash_odr_name (const_tree t)
bool types_same_for_odr (const_tree type1, const_tree type2)
bool types_odr_comparable (tree t1, tree t2)
bool types_must_be_same_for_odr (tree t1, tree t2)
static tree compound_type_base (const_tree t)
bool odr_or_derived_type_p (const_tree t)
void set_type_binfo (tree type, tree binfo)
static bool type_variants_equivalent_p (tree t1, tree t2)
static bool odr_subtypes_equivalent_p (tree t1, tree t2, hash_set< type_pair > *visited, location_t loc1, location_t loc2)
static bool methods_equal_p (tree decl1, tree decl2)
void compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
static bool type_mismatch_p (tree t1, tree t2)
void warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2)
static bool skip_in_fields_list_p (tree t)
bool odr_types_equivalent_p (tree type1, tree type2)
static bool add_type_duplicate (odr_type val, tree type)
tree obj_type_ref_class (const_tree ref, bool for_dump_p)
odr_type get_odr_type (tree type, bool insert)
tree prevailing_odr_type (tree type)
void enable_odr_based_tbaa (tree type)
bool odr_based_tbaa_p (const_tree type)
void set_type_canonical_for_odr_type (tree type, tree canonical)
bool odr_type_violation_reported_p (tree type)
void register_odr_type (tree type)
bool type_known_to_have_no_derivations_p (tree t)
static void dump_odr_type (FILE *f, odr_type t, int indent=0)
static void dump_type_inheritance_graph (FILE *f)
static void free_odr_warning_data ()
void build_type_inheritance_graph (void)
static bool referenced_from_vtable_p (struct cgraph_node *node)
static bool is_cxa_pure_virtual_p (tree target)
static void maybe_record_node (vec< cgraph_node * > &nodes, tree target, hash_set< tree > *inserted, bool can_refer, bool *completep)
static void record_target_from_binfo (vec< cgraph_node * > &nodes, vec< tree > *bases_to_consider, tree binfo, tree otr_type, vec< tree > &type_binfos, HOST_WIDE_INT otr_token, tree outer_type, HOST_WIDE_INT offset, hash_set< tree > *inserted, hash_set< tree > *matched_vtables, bool anonymous, bool *completep)
static void possible_polymorphic_call_targets_1 (vec< cgraph_node * > &nodes, hash_set< tree > *inserted, hash_set< tree > *matched_vtables, tree otr_type, odr_type type, HOST_WIDE_INT otr_token, tree outer_type, HOST_WIDE_INT offset, bool *completep, vec< tree > &bases_to_consider, bool consider_construction)
static void free_polymorphic_call_targets_hash ()
void rebuild_type_inheritance_graph ()
static void devirt_node_removal_hook (struct cgraph_node *n, void *d)
tree subbinfo_with_vtable_at_offset (tree binfo, unsigned HOST_WIDE_INT offset, tree vtable)
bool vtable_pointer_value_to_vtable (const_tree t, tree *v, unsigned HOST_WIDE_INT *offset)
tree vtable_pointer_value_to_binfo (const_tree t)
static void record_targets_from_bases (tree otr_type, HOST_WIDE_INT otr_token, tree outer_type, HOST_WIDE_INT offset, vec< cgraph_node * > &nodes, hash_set< tree > *inserted, hash_set< tree > *matched_vtables, bool *completep)
static void devirt_variable_node_removal_hook (varpool_node *n, void *d)
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)
bool add_decl_warning (const tree &key, const decl_warn_count &value, vec< const decl_warn_count * > *vec)
static void dump_targets (FILE *f, vec< cgraph_node * > targets, bool verbose)
void dump_possible_polymorphic_call_targets (FILE *f, tree otr_type, HOST_WIDE_INT otr_token, const ipa_polymorphic_call_context &ctx, bool verbose)
bool possible_polymorphic_call_target_p (tree otr_type, HOST_WIDE_INT otr_token, const ipa_polymorphic_call_context &ctx, struct cgraph_node *n)
bool possible_polymorphic_call_target_p (tree ref, gimple *stmt, struct cgraph_node *n)
void update_type_inheritance_graph (void)
bool likely_target_p (struct cgraph_node *n)
static int type_warning_cmp (const void *p1, const void *p2)
static int decl_warning_cmp (const void *p1, const void *p2)
struct cgraph_nodetry_speculative_devirtualization (tree otr_type, HOST_WIDE_INT otr_token, ipa_polymorphic_call_context ctx)
static unsigned int ipa_devirt (void)
ipa_opt_pass_dmake_pass_ipa_devirt (gcc::context *ctxt)
DEBUG_FUNCTION void debug_tree_odr_name (tree type, bool demangle)
void register_odr_enum (tree t)
static void ipa_odr_summary_write (void)
static void ipa_odr_read_section (struct lto_file_decl_data *file_data, const char *data, size_t len)
static void ipa_odr_summary_read (void)
ipa_opt_pass_dmake_pass_ipa_odr (gcc::context *ctxt)


bool thunk_expansion
static bool odr_violation_reported = false
static hash_set< cgraph_node * > * cached_polymorphic_call_targets
static odr_hash_typeodr_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_typepolymorphic_call_target_hash
class final_warning_recordfinal_warning_records

Macro Definition Documentation

◆ odr_types

Typedef Documentation

◆ odr_hash_type

ODR type hash used to look up ODR type based on tree type node.   

◆ polymorphic_call_target_hash_type

Function Documentation

◆ add_decl_warning()

bool add_decl_warning ( const tree & key,
const decl_warn_count & value,
vec< const decl_warn_count * > * vec )

Referenced by ipa_devirt().

◆ add_type_duplicate()

static bool add_type_duplicate ( odr_type val,
tree type )
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(), ggc_alloc(), 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().

◆ build_type_inheritance_graph()

◆ can_be_name_hashed_p()

static bool can_be_name_hashed_p ( tree t)

References ggc_alloc(), and odr_type_p().

Referenced by add_type_duplicate(), and get_odr_type().

◆ compare_virtual_tables()

void compare_virtual_tables ( varpool_node * prevailing,
varpool_node * vtable )

◆ compound_type_base()

static tree compound_type_base ( const_tree t)
If T is compound type, return type it is based on.   


Referenced by odr_or_derived_type_p().

◆ debug_tree_odr_name()

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(), and ggc_alloc().

◆ decl_warning_cmp()

static int decl_warning_cmp ( const void * p1,
const void * p2 )
Compare decl warning records P1 and P2 and choose one with larger count;
helper for qsort.   

References decl_warn_count::count, decl_warn_count::dyn_count, and ggc_alloc().

Referenced by ipa_devirt().

◆ devirt_node_removal_hook()

static void devirt_node_removal_hook ( struct cgraph_node * n,
void * d )
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().

◆ devirt_variable_node_removal_hook()

static void devirt_variable_node_removal_hook ( varpool_node * n,
void * d )

◆ dump_odr_type()

◆ dump_possible_polymorphic_call_targets()

◆ dump_targets()

static void dump_targets ( FILE * f,
vec< cgraph_node * > targets,
bool verbose )
Dump target list TARGETS into FILE.   

References DECL_DECLARED_INLINE_P, free(), ggc_alloc(), i, NULL, and verbose.

Referenced by dump_possible_polymorphic_call_targets().

◆ dump_type_inheritance_graph()

static void dump_type_inheritance_graph ( FILE * f)

◆ enable_odr_based_tbaa()

void enable_odr_based_tbaa ( tree type)
Set tbaa_enabled flag for TYPE.   

References get_odr_type(), and odr_type_d::tbaa_enabled.

◆ free_odr_warning_data()

static void free_odr_warning_data ( )
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 ggc_alloc(), i, odr_types, odr_types_ptr, TREE_TYPE, TYPE_NAME, and void_type_node.

Referenced by build_type_inheritance_graph().

◆ free_polymorphic_call_targets_hash()

static void free_polymorphic_call_targets_hash ( )

◆ get_odr_type()

◆ hash_odr_name()

◆ ipa_devirt()

static unsigned int ipa_devirt ( void )
The ipa-devirt pass.
When polymorphic call has only one likely target in the unit,
turn it into a speculative call.   

References add_decl_warning(), symtab_node::alias, profile_count::apply_scale(), AVAIL_INTERPOSABLE, cgraph_edge::call_stmt, 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, dump_enabled_p(), dump_file, dump_flags, symtab_node::dump_name(), dump_possible_polymorphic_call_targets(), dump_printf_loc(), dump_type_inheritance_graph(), final_warning_record::dyn_count, final_warning_records, FOR_EACH_DEFINED_FUNCTION, free_polymorphic_call_targets_hash(), ggc_alloc(), 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, 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().

◆ ipa_odr_read_section()

◆ ipa_odr_summary_read()

◆ ipa_odr_summary_write()

◆ is_cxa_pure_virtual_p()

static bool is_cxa_pure_virtual_p ( tree target)
Return if TARGET is cxa_pure_virtual.   

References DECL_NAME, ggc_alloc(), id_equal(), TREE_CODE, and TREE_TYPE.

Referenced by maybe_record_node(), and possible_polymorphic_call_target_p().

◆ likely_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, ggc_alloc(), lookup_attribute(), NODE_FREQUENCY_NORMAL, referenced_from_vtable_p(), TREE_CODE, and TREE_TYPE.

Referenced by ipa_devirt(), and try_speculative_devirtualization().

◆ make_pass_ipa_devirt()

ipa_opt_pass_d * make_pass_ipa_devirt ( gcc::context * ctxt)

References ggc_alloc().

◆ make_pass_ipa_odr()

ipa_opt_pass_d * make_pass_ipa_odr ( gcc::context * ctxt)

References ggc_alloc().

◆ maybe_record_node()

static void maybe_record_node ( vec< cgraph_node * > & nodes,
tree target,
hash_set< tree > * inserted,
bool can_refer,
bool * completep )
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

References symtab_node::alias_target, AVAIL_AVAILABLE, cached_polymorphic_call_targets, DECL_CONTEXT, DECL_EXTERNAL, gcc_assert, cgraph_node::get(), ggc_alloc(), inserted, is_cxa_pure_virtual_p(), NULL, referenced_from_vtable_p(), SANITIZE_UNREACHABLE, TREE_CODE, TREE_PUBLIC, TREE_TYPE, and type_in_anonymous_namespace_p().

Referenced by possible_polymorphic_call_targets(), record_target_from_binfo(), and record_targets_from_bases().

◆ methods_equal_p()

static bool methods_equal_p ( tree decl1,
tree decl2 )
Return true if DECL1 and DECL2 are identical methods.  Consider
name equivalent to name.localalias.xyz.   

References DECL_ASSEMBLER_NAME, ggc_alloc(), IDENTIFIER_POINTER, and symbol_table::symbol_suffix_separator().

Referenced by compare_virtual_tables().

◆ obj_type_ref_class()

◆ odr_based_tbaa_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().

◆ odr_or_derived_type_p()

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(), ggc_alloc(), 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().

◆ odr_subtypes_equivalent_p()

◆ odr_type_violation_reported_p()

bool odr_type_violation_reported_p ( tree type)
Return true if we reported some ODR violation on TYPE.   

References get_odr_type(), and odr_type_d::odr_violated.

◆ odr_types_equivalent_p() [1/2]

bool odr_types_equivalent_p ( tree type1,
tree type2 )
Return true if TYPE1 and TYPE2 are equivalent for One Definition Rule.   

References gcc_checking_assert, ggc_alloc(), NULL, odr_or_derived_type_p(), odr_types_equivalent_p(), UNKNOWN_LOCATION, and visited.

◆ odr_types_equivalent_p() [2/2]

static bool odr_types_equivalent_p ( tree t1,
tree t2,
bool warn,
bool * warned,
hash_set< type_pair > * visited,
location_t loc1,
location_t loc2 )

◆ possible_polymorphic_call_target_p() [1/2]

◆ possible_polymorphic_call_target_p() [2/2]

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, ggc_alloc(), 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().

◆ possible_polymorphic_call_targets()

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 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(), ggc_alloc(), gimple_get_virt_method_for_binfo(), final_warning_record::grow_type_warnings(), i, odr_type_d::id, inserted, 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, type(), odr_type_d::type, polymorphic_call_target_d::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().

◆ possible_polymorphic_call_targets_1()

static void possible_polymorphic_call_targets_1 ( vec< cgraph_node * > & nodes,
hash_set< tree > * inserted,
hash_set< tree > * matched_vtables,
tree otr_type,
odr_type type,
HOST_WIDE_INT otr_token,
tree outer_type,
bool * completep,
vec< tree > & bases_to_consider,
bool consider_construction )
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.

all cases where BASE_SKIPPED is true (because the base is abstract

References ggc_alloc(), i, inserted, 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().

◆ prevailing_odr_type()

tree prevailing_odr_type ( tree type)
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, type(), and odr_type_d::type.

Referenced by get_alias_set().

◆ rebuild_type_inheritance_graph()

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.

◆ record_target_from_binfo()

static void record_target_from_binfo ( vec< cgraph_node * > & nodes,
vec< tree > * bases_to_consider,
tree binfo,
tree otr_type,
vec< tree > & type_binfos,
HOST_WIDE_INT otr_token,
tree outer_type,
hash_set< tree > * inserted,
hash_set< tree > * matched_vtables,
bool anonymous,
bool * completep )
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

ANONYMOUS is true if BINFO is part of anonymous namespace.

Clear COMPLETEP when we hit unreferable target.

References BINFO_BASE_ITERATE, BINFO_OFFSET, BINFO_TYPE, BINFO_VTABLE, DECL_CXX_DESTRUCTOR_P, gcc_assert, varpool_node::get(), get_binfo_at_offset(), ggc_alloc(), gimple_get_virt_method_for_binfo(), i, inserted, 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().

◆ record_targets_from_bases()

static void record_targets_from_bases ( tree otr_type,
HOST_WIDE_INT otr_token,
tree outer_type,
vec< cgraph_node * > & nodes,
hash_set< tree > * inserted,
hash_set< tree > * matched_vtables,
bool * completep )
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 BINFO_VTABLE, DECL_ARTIFICIAL, DECL_CHAIN, DECL_CXX_DESTRUCTOR_P, DECL_SIZE, gcc_assert, get_binfo_at_offset(), ggc_alloc(), gimple_get_virt_method_for_binfo(), inserted, 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().

◆ referenced_from_vtable_p()

static bool referenced_from_vtable_p ( struct cgraph_node * node)
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, symtab_node::externally_visible, ggc_alloc(), 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().

◆ register_odr_enum()

void register_odr_enum ( tree t)
Register ODR enum so we later stream record about its values.   

References ggc_alloc(), odr_enums, and vec_safe_push().

◆ register_odr_type()

◆ set_type_binfo()

void set_type_binfo ( tree type,
tree binfo )
Set TYPE_BINFO of TYPE and its variants to BINFO.   

References COMPLETE_TYPE_P, gcc_assert, ggc_alloc(), type(), TYPE_BINFO, and TYPE_NEXT_VARIANT.

Referenced by add_type_duplicate().

◆ set_type_canonical_for_odr_type()

void set_type_canonical_for_odr_type ( tree type,
tree canonical )
Set TYPE_CANONICAL of type and all its variants and duplicates

References FOR_EACH_VEC_ELT, get_odr_type(), ggc_alloc(), i, odr_type_d::type, TYPE_CANONICAL, TYPE_NEXT_VARIANT, and odr_type_d::types.

◆ skip_in_fields_list_p()

static bool skip_in_fields_list_p ( tree t)
Return true if T should be ignored in TYPE_FIELDS for ODR comparison.   

References DECL_ARTIFICIAL, DECL_IGNORED_P, DECL_NAME, DECL_SIZE, ggc_alloc(), integer_zerop(), and TREE_CODE.

Referenced by odr_types_equivalent_p().

◆ subbinfo_with_vtable_at_offset()

◆ try_speculative_devirtualization()

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, DECL_ARTIFICIAL, DECL_EXTERNAL, ggc_alloc(), 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().

◆ type_all_ctors_visible_p()

static bool type_all_ctors_visible_p ( tree t)
Return TRUE if type's constructors are all visible.   

References CONSTRUCTION, ggc_alloc(), symbol_table::state, symtab, and type_in_anonymous_namespace_p().

Referenced by type_possibly_instantiated_p().

◆ type_all_derivations_known_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(), ggc_alloc(), 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().

◆ type_known_to_have_no_derivations_p()

bool type_known_to_have_no_derivations_p ( tree t)
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().

◆ type_mismatch_p()

static bool type_mismatch_p ( tree t1,
tree t2 )
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().

◆ type_or_derived_type_possibly_instantiated_p()

static bool type_or_derived_type_possibly_instantiated_p ( odr_type t)

◆ type_possibly_instantiated_p()

◆ type_variants_equivalent_p()

static bool type_variants_equivalent_p ( tree t1,
tree t2 )
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().

◆ type_warning_cmp()

static int type_warning_cmp ( const void * p1,
const void * p2 )
Compare type warning records P1 and P2 and choose one with larger count;
helper for qsort.   

References odr_type_warn_count::count, odr_type_warn_count::dyn_count, and ggc_alloc().

Referenced by ipa_devirt().

◆ types_must_be_same_for_odr()

◆ types_odr_comparable()

bool types_odr_comparable ( tree t1,
tree t2 )

◆ types_same_for_odr()

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, ggc_alloc(), 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().

◆ update_type_inheritance_graph()

void update_type_inheritance_graph ( void )

◆ vtable_pointer_value_to_binfo()

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, ggc_alloc(), NULL_TREE, offset, subbinfo_with_vtable_at_offset(), TYPE_BINFO, and vtable_pointer_value_to_vtable().

◆ 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, ggc_alloc(), 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().

◆ warn_odr()

static void warn_odr ( tree t1,
tree t2,
tree st1,
tree st2,
bool warn,
bool * warned,
const char * reason )
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

References lto_location_cache::apply_location_cache(), lto_location_cache::current_cache, DECL_SOURCE_LOCATION, ggc_alloc(), inform(), NULL, TREE_CODE, TYPE_MAIN_VARIANT, TYPE_NAME, and warning_at().

Referenced by add_type_duplicate(), and odr_types_equivalent_p().

◆ warn_types_mismatch()

void warn_types_mismatch ( tree t1,
tree t2,
location_t loc1,
location_t loc2 )
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(), ggc_alloc(), 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().

Variable Documentation

◆ cached_polymorphic_call_targets

hash_set<cgraph_node *>* cached_polymorphic_call_targets

◆ final_warning_records

class final_warning_record* final_warning_records

◆ odr_enum_map

hash_map<nofree_string_hash, odr_enum>* odr_enum_map = NULL
A table of all ODR enum definitions.   

Referenced by ipa_odr_read_section(), ipa_odr_summary_read(), and ipa_odr_summary_write().

◆ odr_enum_obstack

◆ odr_enums

vec<tree, va_gc>* odr_enums
All enums defined and accessible for the unit.   

Referenced by ipa_odr_summary_write(), and register_odr_enum().

◆ odr_hash

◆ odr_types_ptr

vec<odr_type, va_gc>* odr_types_ptr
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().

◆ odr_violation_reported

◆ polymorphic_call_target_hash

◆ thunk_expansion

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().