GCC Middle and Back End API Reference
ipa_polymorphic_call_context Class Reference

#include <cgraph.h>

Public Member Functions

 ipa_polymorphic_call_context ()
 
 ipa_polymorphic_call_context (cgraph_edge *e)
 
 ipa_polymorphic_call_context (tree cst, tree otr_type=NULL, HOST_WIDE_INT offset=0)
 
 ipa_polymorphic_call_context (tree fndecl, tree ref, gimple *stmt, tree *instance=NULL)
 
bool get_dynamic_type (tree, tree, tree, gimple *, unsigned *)
 
void clear_speculation ()
 
void clear_outer_type (tree otr_type=NULL)
 
bool restrict_to_inner_class (tree otr_type, bool consider_placement_new=true, bool consider_bases=true)
 
void offset_by (HOST_WIDE_INT)
 
void possible_dynamic_type_change (bool, tree otr_type=NULL)
 
bool combine_with (ipa_polymorphic_call_context, tree otr_type=NULL)
 
bool meet_with (ipa_polymorphic_call_context, tree otr_type=NULL)
 
bool useless_p () const
 
bool equal_to (const ipa_polymorphic_call_context &x) const
 
void dump (FILE *f, bool newline=true) const
 
void DEBUG_FUNCTION debug () const
 
void stream_out (struct output_block *) const
 
void stream_in (class lto_input_block *, class data_in *data_in)
 

Data Fields

HOST_WIDE_INT offset
 
HOST_WIDE_INT speculative_offset
 
tree outer_type
 
tree speculative_outer_type
 
unsigned maybe_in_construction: 1
 
unsigned maybe_derived_type: 1
 
unsigned speculative_maybe_derived_type: 1
 
unsigned invalid: 1
 
unsigned dynamic: 1
 

Private Member Functions

bool combine_speculation_with (tree, HOST_WIDE_INT, bool, tree)
 
bool meet_speculation_with (tree, HOST_WIDE_INT, bool, tree)
 
void set_by_decl (tree, HOST_WIDE_INT)
 
bool set_by_invariant (tree, tree, HOST_WIDE_INT)
 
bool speculation_consistent_p (tree, HOST_WIDE_INT, bool, tree) const
 
void make_speculative (tree otr_type=NULL)
 

Detailed Description

Context of polymorphic call. It represent information about the type of
instance that may reach the call.  This is used by ipa-devirt walkers of the
type inheritance graph.   

Constructor & Destructor Documentation

◆ ipa_polymorphic_call_context() [1/4]

ipa_polymorphic_call_context::ipa_polymorphic_call_context ( )
inline
Build empty "I know nothing" context.   

References clear_outer_type(), clear_speculation(), and invalid.

◆ ipa_polymorphic_call_context() [2/4]

ipa_polymorphic_call_context::ipa_polymorphic_call_context ( cgraph_edge * e)
inline

◆ ipa_polymorphic_call_context() [3/4]

ipa_polymorphic_call_context::ipa_polymorphic_call_context ( tree cst,
tree otr_type = NULL,
HOST_WIDE_INT off = 0 )
Create polymorphic call context from IP invariant CST.
This is typically &global_var.
OTR_TYPE specify type of polymorphic call or NULL if unknown, OFF
is offset of call.   

References clear_speculation(), and set_by_invariant().

◆ ipa_polymorphic_call_context() [4/4]

Member Function Documentation

◆ clear_outer_type()

void ipa_polymorphic_call_context::clear_outer_type ( tree otr_type = NULL)
inline
Produce context specifying all derived types of OTR_TYPE.  If OTR_TYPE is
NULL, the context is set to dummy "I know nothing" setting.   

References dynamic, maybe_derived_type, maybe_in_construction, NULL, offset, outer_type, and TYPE_MAIN_VARIANT.

Referenced by combine_with(), ipa_polymorphic_call_context(), ipa_polymorphic_call_context(), make_speculative(), meet_with(), possible_polymorphic_call_targets(), restrict_to_inner_class(), set_by_decl(), and set_by_invariant().

◆ clear_speculation()

◆ combine_speculation_with()

bool ipa_polymorphic_call_context::combine_speculation_with ( tree new_outer_type,
HOST_WIDE_INT new_offset,
bool new_maybe_derived_type,
tree otr_type )
private
Improve THIS with speculation described by NEW_OUTER_TYPE, NEW_OFFSET,
NEW_MAYBE_DERIVED_TYPE 
If OTR_TYPE is set, assume the context is used with OTR_TYPE.   

References clear_speculation(), contains_type_p(), dump_file, dump_flags, restrict_to_inner_class(), speculation_consistent_p(), speculative_maybe_derived_type, speculative_offset, speculative_outer_type, TDF_DETAILS, and types_must_be_same_for_odr().

Referenced by combine_with(), ipa_polymorphic_call_context(), and make_speculative().

◆ combine_with()

bool ipa_polymorphic_call_context::combine_with ( ipa_polymorphic_call_context ctx,
tree otr_type = NULL )

◆ debug()

void ipa_polymorphic_call_context::debug ( ) const
Print context to stderr.   

References dump().

◆ dump()

◆ equal_to()

◆ get_dynamic_type()

bool ipa_polymorphic_call_context::get_dynamic_type ( tree instance,
tree otr_object,
tree otr_type,
gimple * call,
unsigned * aa_walk_budget_p )
THIS is polymorphic call context obtained from get_polymorphic_context.
OTR_OBJECT is pointer to the instance returned by OBJ_TYPE_REF_OBJECT.
INSTANCE is pointer to the outer instance as returned by
get_polymorphic_context.  To avoid creation of temporary expressions,
INSTANCE may also be an declaration of get_polymorphic_context found the
value to be in static storage.

If the type of instance is not fully determined
(either OUTER_TYPE is unknown or MAYBE_IN_CONSTRUCTION/INCLUDE_DERIVED_TYPES
is set), try to walk memory writes and find the actual construction of the
instance.

Return true if memory is unchanged from function entry.

We do not include this analysis in the context analysis itself, because
it needs memory SSA to be fully built and the walk may be expensive.
So it is not suitable for use withing fold_stmt and similar uses.

AA_WALK_BUDGET_P, if not NULL, is how statements we should allow
walk_aliased_vdefs to examine.  The value should be decremented by the
number of statements we examined or set to zero if exhausted.   

References ao_ref_init(), ao_ref_init_from_ptr_and_size(), BINFO_VTABLE, check_stmt_for_type_change(), DECL_P, dump_file, dynamic, get_alias_set(), get_base_address(), get_ref_base_and_extent_hwi(), gimple_assign_load_p(), gimple_assign_rhs1(), gimple_call_fn(), gimple_vuse(), type_change_info::instance, is_gimple_min_invariant(), type_change_info::known_current_offset, type_change_info::known_current_type, maybe_derived_type, maybe_in_construction, type_change_info::multiple_types_encountered, NULL, NULL_TREE, OBJ_TYPE_REF_EXPR, offset, type_change_info::offset, type_change_info::otr_type, outer_type, POINTER_SIZE, print_generic_expr(), print_gimple_stmt(), restrict_to_inner_class(), type_change_info::seen_unanalyzed_store, type_change_info::speculative, speculative_maybe_derived_type, speculative_offset, speculative_outer_type, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, TDF_SLIM, TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_BINFO, TYPE_MAIN_VARIANT, type_change_info::type_maybe_changed, types_same_for_odr(), type_change_info::vtbl_ptr_ref, walk_aliased_vdefs(), and walk_ssa_copies().

Referenced by eliminate_dom_walker::eliminate_stmt(), ipa_analyze_call_uses(), and ipa_compute_jump_functions_for_edge().

◆ make_speculative()

void ipa_polymorphic_call_context::make_speculative ( tree otr_type = NULL)
private
Take non-speculative info, merge it with speculative and clear speculation.
Used when we no longer manage to keep track of actual outer type, but we
think it is still there.

If OTR_TYPE is set, the transformation can be done more effectively assuming
that context is going to be used only that way.   

References clear_outer_type(), clear_speculation(), combine_speculation_with(), invalid, maybe_derived_type, offset, and outer_type.

Referenced by possible_dynamic_type_change().

◆ meet_speculation_with()

bool ipa_polymorphic_call_context::meet_speculation_with ( tree new_outer_type,
HOST_WIDE_INT new_offset,
bool new_maybe_derived_type,
tree otr_type )
private
Make speculation less specific so
NEW_OUTER_TYPE, NEW_OFFSET, NEW_MAYBE_DERIVED_TYPE is also included.
If OTR_TYPE is set, assume the context is used with OTR_TYPE.   

References clear_speculation(), contains_type_p(), dump_file, dump_flags, restrict_to_inner_class(), speculation_consistent_p(), speculative_maybe_derived_type, speculative_offset, speculative_outer_type, TDF_DETAILS, and types_must_be_same_for_odr().

Referenced by meet_with().

◆ meet_with()

◆ offset_by()

void ipa_polymorphic_call_context::offset_by ( HOST_WIDE_INT off)
inline

◆ possible_dynamic_type_change()

void ipa_polymorphic_call_context::possible_dynamic_type_change ( bool in_poly_cdtor,
tree otr_type = NULL )
Use when we cannot track dynamic type change.  This speculatively assume
type change is not happening.   

References dynamic, make_speculative(), and maybe_in_construction.

Referenced by ipa_context_from_jfunc(), ipa_get_indirect_edge_target_1(), propagate_context_across_jump_function(), try_make_edge_direct_virtual_call(), and update_jump_functions_after_inlining().

◆ restrict_to_inner_class()

bool ipa_polymorphic_call_context::restrict_to_inner_class ( tree otr_type,
bool consider_placement_new = true,
bool consider_bases = true )
THIS->OUTER_TYPE is a type of memory object where object of OTR_TYPE
is contained at THIS->OFFSET.  Walk the memory representation of
THIS->OUTER_TYPE and find the outermost class type that match
OTR_TYPE or contain OTR_TYPE as a base.  Update THIS
to represent it.

If OTR_TYPE is NULL, just find outermost polymorphic type with
virtual table present at position OFFSET.

For example when THIS represents type
class A
  {
    int a;
    class B b;
  }
and we look for type at offset sizeof(int), we end up with B and offset 0.
If the same is produced by multiple inheritance, we end up with A and offset
sizeof(int). 

If we cannot find corresponding class, give up by setting
THIS->OUTER_TYPE to OTR_TYPE and THIS->OFFSET to NULL. 
Return true when lookup was successful.

When CONSIDER_PLACEMENT_NEW is false, reject contexts that may be made
valid only via allocation of new polymorphic type inside by means
of placement new.

When CONSIDER_BASES is false, only look for actual fields, not base types
of TYPE.   

References clear_outer_type(), clear_speculation(), contains_polymorphic_type_p(), DECL_ARTIFICIAL, DECL_CHAIN, DECL_SIZE, dynamic, error_mark_node, get_binfo_at_offset(), int_bit_position(), invalid, maybe_derived_type, odr_type_p(), offset, outer_type, POINTER_SIZE, POINTER_TYPE_P, polymorphic_type_binfo_p(), possible_placement_new(), size_unknown(), speculation_consistent_p(), speculative_maybe_derived_type, speculative_offset, speculative_outer_type, TREE_CODE, tree_fits_shwi_p(), tree_fits_uhwi_p(), tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, type(), TYPE_BINFO, TYPE_FIELDS, type_known_to_have_no_derivations_p(), TYPE_MAIN_VARIANT, TYPE_SIZE, type_with_linkage_p(), types_must_be_same_for_odr(), types_odr_comparable(), and types_same_for_odr().

Referenced by combine_speculation_with(), combine_with(), contains_type_p(), get_dynamic_type(), meet_speculation_with(), meet_with(), possible_polymorphic_call_targets(), and record_known_type().

◆ set_by_decl()

void ipa_polymorphic_call_context::set_by_decl ( tree base,
HOST_WIDE_INT off )
private
Produce polymorphic call context for call method of instance
that is located within BASE (that is assumed to be a decl) at offset OFF.  

References clear_outer_type(), clear_speculation(), contains_polymorphic_type_p(), DECL_P, dynamic, gcc_assert, maybe_derived_type, maybe_in_construction, offset, outer_type, TREE_TYPE, and TYPE_MAIN_VARIANT.

Referenced by ipa_polymorphic_call_context(), and set_by_invariant().

◆ set_by_invariant()

bool ipa_polymorphic_call_context::set_by_invariant ( tree cst,
tree otr_type,
HOST_WIDE_INT off )
private
CST is an invariant (address of decl), try to get meaningful
polymorphic call context for polymorphic call of method 
if instance of OTR_TYPE that is located at offset OFF of this invariant.
Return FALSE if nothing meaningful can be found.   

References clear_outer_type(), contains_type_p(), DECL_P, get_ref_base_and_extent(), invalid, set_by_decl(), TREE_CODE, TREE_OPERAND, and TREE_TYPE.

Referenced by ipa_polymorphic_call_context().

◆ speculation_consistent_p()

bool ipa_polymorphic_call_context::speculation_consistent_p ( tree spec_outer_type,
HOST_WIDE_INT spec_offset,
bool spec_maybe_derived_type,
tree otr_type ) const
private
See if speculation given by SPEC_OUTER_TYPE, SPEC_OFFSET and SPEC_MAYBE_DERIVED_TYPE
seems consistent (and useful) with what we already have in the non-speculative context.   

References contains_polymorphic_type_p(), contains_type_p(), maybe_derived_type, odr_type_p(), offset, outer_type, and types_must_be_same_for_odr().

Referenced by combine_speculation_with(), equal_to(), meet_speculation_with(), and restrict_to_inner_class().

◆ stream_in()

◆ stream_out()

◆ useless_p()

Field Documentation

◆ dynamic

◆ invalid

◆ maybe_derived_type

◆ maybe_in_construction

◆ offset

◆ outer_type

◆ speculative_maybe_derived_type

◆ speculative_offset

◆ speculative_outer_type


The documentation for this class was generated from the following files: