GCC Middle and Back End API Reference
|
#include <cgraph.h>
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) |
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.
|
inline |
Build empty "I know nothing" context.
References clear_outer_type(), clear_speculation(), and invalid.
|
inline |
Build polymorphic call context for indirect call E.
References cgraph_indirect_call_info::context, gcc_checking_assert, cgraph_edge::indirect_info, and cgraph_indirect_call_info::polymorphic.
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::ipa_polymorphic_call_context | ( | tree | fndecl, |
tree | ref, | ||
gimple * | stmt, | ||
tree * | instance = NULL ) |
Build context for pointer REF contained in FNDECL at statement STMT. if INSTANCE is non-NULL, return pointer to the object described by the context or DECL where context is contained in.
References clear_outer_type(), clear_speculation(), combine_speculation_with(), contains_polymorphic_type_p(), contains_type_p(), current_function_decl, DECL_ARGUMENTS, DECL_BY_REFERENCE, DECL_CXX_CONSTRUCTOR_P, DECL_CXX_DESTRUCTOR_P, decl_maybe_in_construction_p(), DECL_P, dynamic, wi::fits_shwi_p(), thunk_info::fixed_offset, gcc_assert, cgraph_node::get(), thunk_info::get(), get_ref_base_and_extent_hwi(), gimple_assign_rhs1(), gimple_assign_single_p(), invalid, maybe_derived_type, maybe_in_construction, mem_ref_offset(), NULL, obj_type_ref_class(), OBJ_TYPE_REF_OBJECT, offset, outer_type, POINTER_TYPE_P, set_by_decl(), SIGNED, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_VAR, wi::to_wide(), TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_MAIN_VARIANT, thunk_info::virtual_offset_p, visited, and walk_ssa_copies().
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().
|
inline |
Make context non-speculative.
References NULL, speculative_maybe_derived_type, speculative_offset, and speculative_outer_type.
Referenced by combine_speculation_with(), combine_with(), ipa_polymorphic_call_context(), ipa_polymorphic_call_context(), ipa_polymorphic_call_context(), make_speculative(), meet_speculation_with(), possible_polymorphic_call_targets(), restrict_to_inner_class(), and set_by_decl().
|
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().
bool ipa_polymorphic_call_context::combine_with | ( | ipa_polymorphic_call_context | ctx, |
tree | otr_type = NULL ) |
Assume that both THIS and a given context is valid and strengthen THIS if possible. Return true if any strengthening was made. If actual type the context is being used in is known, OTR_TYPE should be set accordingly. This improves quality of combined result.
References clear_outer_type(), clear_speculation(), combine_speculation_with(), contains_type_p(), dump(), dump_file, dump_flags, dynamic, invalid, invalidate(), maybe_derived_type, maybe_in_construction, offset, outer_type, print_generic_expr(), restrict_to_inner_class(), speculative_maybe_derived_type, speculative_offset, speculative_outer_type, TDF_DETAILS, TDF_SLIM, TREE_CODE, TYPE_SIZE, types_must_be_same_for_odr(), types_odr_comparable(), and useless_p().
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().
void ipa_polymorphic_call_context::debug | ( | ) | const |
Print context to stderr.
References dump().
Dump human readable context to F. If NEWLINE is true, it will be terminated by a newline.
References dynamic, HOST_WIDE_INT_PRINT_DEC, invalid, maybe_derived_type, maybe_in_construction, offset, outer_type, print_generic_expr(), speculative_maybe_derived_type, speculative_offset, speculative_outer_type, TDF_SLIM, and useless_p().
Referenced by combine_with(), debug(), dump_possible_polymorphic_call_targets(), ipa_print_node_jump_functions(), ipa_print_node_jump_functions_for_edge(), meet_with(), and print_ipcp_constant_value().
bool ipa_polymorphic_call_context::equal_to | ( | const ipa_polymorphic_call_context & | x | ) | const |
Return TRUE if this context conveys the same information as OTHER.
References dynamic, invalid, maybe_derived_type, maybe_in_construction, NULL, NULL_TREE, offset, outer_type, speculation_consistent_p(), speculative_maybe_derived_type, speculative_offset, speculative_outer_type, types_odr_comparable(), types_same_for_odr(), and useless_p().
Referenced by meet_with(), propagate_context_across_jump_function(), and values_equal_for_ipcp_p().
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().
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().
|
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().
bool ipa_polymorphic_call_context::meet_with | ( | ipa_polymorphic_call_context | ctx, |
tree | otr_type = NULL ) |
Modify context to be strictly less restrictive than CTX.
References clear_outer_type(), contains_type_p(), dump(), dump_file, dump_flags, dynamic, equal_to(), invalid, maybe_derived_type, maybe_in_construction, meet_speculation_with(), offset, operand_equal_p(), outer_type, print_generic_expr(), restrict_to_inner_class(), speculative_maybe_derived_type, speculative_offset, speculative_outer_type, TDF_DETAILS, TDF_SLIM, TREE_CODE, TYPE_SIZE, types_must_be_same_for_odr(), and useless_p().
Referenced by find_more_contexts_for_caller_subset().
|
inline |
Adjust all offsets in contexts by OFF bits.
References offset, outer_type, speculative_offset, and speculative_outer_type.
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().
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().
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().
|
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().
|
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().
|
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().
void ipa_polymorphic_call_context::stream_in | ( | class lto_input_block * | ib, |
class data_in * | data_in ) |
Stream in the context from IB and DATA_IN.
References bp_unpack_value(), dynamic, invalid, maybe_derived_type, maybe_in_construction, NULL, offset, outer_type, speculative_maybe_derived_type, speculative_offset, speculative_outer_type, stream_read_tree, streamer_read_bitpack(), and streamer_read_hwi().
Referenced by ipa_read_edge_info(), and ipa_read_indirect_edge_info().
void ipa_polymorphic_call_context::stream_out | ( | struct output_block * | ob | ) | const |
Stream out the context to OB.
References bitpack_create(), bp_pack_value(), dynamic, gcc_assert, invalid, output_block::main_stream, maybe_derived_type, maybe_in_construction, NULL, offset, outer_type, speculative_maybe_derived_type, speculative_offset, speculative_outer_type, stream_write_tree, streamer_write_bitpack(), and streamer_write_hwi().
Referenced by ipa_write_indirect_edge_info(), and ipa_write_node_info().
|
inline |
Return TRUE if context is fully useless.
References outer_type, and speculative_outer_type.
Referenced by combine_with(), dump(), equal_to(), evaluate_properties_for_edge(), find_more_contexts_for_caller_subset(), ipa_compute_jump_functions_for_edge(), ipa_context_from_jfunc(), ipa_get_indirect_edge_target_1(), ipa_print_node_jump_functions_for_edge(), known_contexts_useful_p(), meet_with(), propagate_context_across_jump_function(), and update_jump_functions_after_inlining().
unsigned ipa_polymorphic_call_context::dynamic |
unsigned ipa_polymorphic_call_context::invalid |
unsigned ipa_polymorphic_call_context::maybe_derived_type |
Referenced by clear_outer_type(), combine_with(), contains_type_p(), dump(), dump_possible_polymorphic_call_targets(), polymorphic_call_target_hasher::equal(), equal_to(), get_dynamic_type(), polymorphic_call_target_hasher::hash(), ipa_polymorphic_call_context(), make_speculative(), meet_with(), possible_polymorphic_call_targets(), record_known_type(), restrict_to_inner_class(), set_by_decl(), speculation_consistent_p(), stream_in(), and stream_out().
unsigned ipa_polymorphic_call_context::maybe_in_construction |
Referenced by clear_outer_type(), combine_with(), dump(), dump_possible_polymorphic_call_targets(), polymorphic_call_target_hasher::equal(), equal_to(), get_dynamic_type(), polymorphic_call_target_hasher::hash(), ipa_polymorphic_call_context(), meet_with(), possible_dynamic_type_change(), possible_polymorphic_call_targets(), record_known_type(), set_by_decl(), stream_in(), and stream_out().
HOST_WIDE_INT ipa_polymorphic_call_context::offset |
Referenced by clear_outer_type(), combine_with(), contains_type_p(), dump(), polymorphic_call_target_hasher::equal(), equal_to(), get_dynamic_type(), polymorphic_call_target_hasher::hash(), ipa_polymorphic_call_context(), make_speculative(), meet_with(), offset_by(), possible_polymorphic_call_targets(), record_known_type(), restrict_to_inner_class(), set_by_decl(), speculation_consistent_p(), stream_in(), and stream_out().
tree ipa_polymorphic_call_context::outer_type |
Referenced by clear_outer_type(), combine_with(), contains_type_p(), dump(), polymorphic_call_target_hasher::equal(), equal_to(), get_dynamic_type(), polymorphic_call_target_hasher::hash(), ipa_polymorphic_call_context(), make_speculative(), meet_with(), offset_by(), possible_polymorphic_call_targets(), record_known_type(), restrict_to_inner_class(), set_by_decl(), speculation_consistent_p(), stream_in(), stream_out(), and useless_p().
unsigned ipa_polymorphic_call_context::speculative_maybe_derived_type |
Referenced by clear_speculation(), combine_speculation_with(), combine_with(), dump(), dump_possible_polymorphic_call_targets(), polymorphic_call_target_hasher::equal(), equal_to(), get_dynamic_type(), polymorphic_call_target_hasher::hash(), meet_speculation_with(), meet_with(), possible_polymorphic_call_targets(), restrict_to_inner_class(), stream_in(), and stream_out().
HOST_WIDE_INT ipa_polymorphic_call_context::speculative_offset |
Referenced by clear_speculation(), combine_speculation_with(), combine_with(), dump(), polymorphic_call_target_hasher::equal(), equal_to(), get_dynamic_type(), polymorphic_call_target_hasher::hash(), meet_speculation_with(), meet_with(), offset_by(), possible_polymorphic_call_targets(), restrict_to_inner_class(), stream_in(), and stream_out().
tree ipa_polymorphic_call_context::speculative_outer_type |
Referenced by clear_speculation(), combine_speculation_with(), combine_with(), dump(), polymorphic_call_target_hasher::equal(), equal_to(), get_dynamic_type(), polymorphic_call_target_hasher::hash(), meet_speculation_with(), meet_with(), offset_by(), possible_polymorphic_call_targets(), restrict_to_inner_class(), stream_in(), stream_out(), and useless_p().