GCC Middle and Back End API Reference
|
Data Structures | |
struct | param_analysis_info |
struct | ipa_cst_ref_desc |
struct | type_change_info |
struct | ipa_known_agg_contents_list |
Variables | |
vec< ipa_node_params_t > | ipa_node_params_vector |
vec < ipa_agg_replacement_value_p, va_gc > * | ipa_node_agg_replacements |
vec< ipa_edge_args_t, va_gc > * | ipa_edge_args_vector |
static struct cgraph_edge_hook_list * | edge_removal_hook_holder |
static struct cgraph_node_hook_list * | node_removal_hook_holder |
static struct cgraph_2edge_hook_list * | edge_duplication_hook_holder |
static struct cgraph_2node_hook_list * | node_duplication_hook_holder |
static struct cgraph_node_hook_list * | function_insertion_hook_holder |
static alloc_pool | ipa_refdesc_pool |
|
static |
Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in NODE.
|
static |
If the value of constant jump function JFUNC is an address of a function declaration, return the associated call graph node. Otherwise return NULL.
Referenced by ipa_find_agg_cst_for_param(), and ipa_free_all_edge_args().
|
static |
Callback of walk_aliased_vdefs and a helper function for detect_type_change to check whether a particular statement may modify the virtual table pointer, and if possible also determine the new type of the (sub-)object. It stores its result into DATA, which points to a type_change_info structure.
|
static |
Combine two controlled uses counts as done during inlining.
|
static |
Update the jump function DST when the call graph edge corresponding to SRC is is being inlined, knowing that DST is of type ancestor and src of known type.
References ipa_pass_through_data::formal_id, ipa_get_ith_jump_func(), ipa_get_jf_known_type_base_type(), ipa_get_jf_known_type_offset(), ipa_get_jf_pass_through_agg_preserved(), IPA_JF_CONST, IPA_JF_KNOWN_TYPE, IPA_JF_PASS_THROUGH, IPA_JF_UNKNOWN, ipa_set_jf_cst_copy(), ipa_set_jf_known_type(), ipa_jump_func::jump_func_value::pass_through, ipa_jump_func::type, and ipa_jump_func::value.
|
static |
Given that an actual argument is an SSA_NAME that is a result of a phi statement PHI, try to find out whether NAME is in fact a multiple-inheritance typecast from a descendant into an ancestor of a formal parameter and thus can be described by an ancestor jump function and if so, write the appropriate function into JFUNC. Essentially we want to match the following pattern: if (obj_2(D) != 0B) goto <bb 3>; else goto <bb 4>; <bb 3>: iftmp.1_3 = &obj_2(D)->D.1762; <bb 4>: # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)> D.1879_6 = middleman_1 (iftmp.1_1, i_5(D)); return D.1879_6;
|
static |
Given that an actual argument is an SSA_NAME (given in NAME) and is a result of an assignment statement STMT, try to determine whether we are actually handling any of the following cases and construct an appropriate jump function into JFUNC if so: 1) The passed value is loaded from a formal parameter which is not a gimple register (most probably because it is addressable, the value has to be scalar) and we can guarantee the value has not changed. This case can therefore be described by a simple pass-through jump function. For example: foo (int a) { int a.0; a.0_2 = a; bar (a.0_2); 2) The passed value can be described by a simple arithmetic pass-through jump function. E.g. foo (int a) { int D.2064; D.2064_4 = a.1(D) + 4; bar (D.2064_4); This case can also occur in combination of the previous one, e.g.: foo (int a, int z) { int a.0; int D.2064; a.0_3 = a; D.2064_4 = a.0_3 + 4; foo (D.2064_4); 3) The passed value is an address of an object within another one (which also passed by reference). Such situations are described by an ancestor jump function and describe situations such as: B::foo() (struct B * const this) { struct A * D.1845; D.1845_2 = &this_1(D)->D.1748; A::bar (D.1845_2); INFO is the structure describing individual parameters access different stages of IPA optimizations. PARMS_AINFO contains the information that is only needed for intraprocedural analysis.
If this is a varying address, punt.
Dynamic types are changed in constructors and destructors.
|
static |
Given OP which is passed as an actual argument to a called function, determine if it is possible to construct a KNOWN_TYPE jump function for it and if so, create one and store it to JFUNC. EXPECTED_TYPE represents a type the argument should be in
Be sure expected_type is polymorphic.
|
inlinestatic |
Return how many formal parameters FNDECL has.
References ipa_node_params::descriptors, and print_generic_expr().
Referenced by ipa_alloc_node_params().
|
static |
Detect whether the dynamic type of ARG of COMP_TYPE has changed (before callsite CALL) by looking for assignments to its virtual table pointer. If it is, return true and fill in the jump function JFUNC with relevant type information or set it to unknown. ARG is the object itself (not a pointer to it, unless dereferenced). BASE is the base of the memory access as returned by get_ref_base_and_extent, as is the offset.
Const calls cannot call virtual methods through VMT and so type changes do not matter.
Be sure expected_type is polymorphic.
Referenced by get_ancestor_addr_info().
|
static |
Like detect_type_change but ARG is supposed to be a non-dereferenced pointer SSA name (its dereference will become the base and the offset is assumed to be zero).
Referenced by ipa_load_from_parm_agg().
|
static |
Traverse statements from CALL backwards, scanning whether an aggregate given in ARG is filled in with constant values. ARG can either be an aggregate expression or a pointer to an aggregate. JFUNC is the jump function into which the constants are subsequently stored.
The function operates in three stages. First, we prepare check_ref, r, arg_base and arg_offset based on what is actually passed as an actual argument.
Second stage walks back the BB, looks at individual statements and as long as it is confident of how the statements affect contents of the aggregates, it builds a sorted linked list of ipa_agg_jf_list structures describing it.
We already know this value is subsequently overwritten with something else.
Otherwise this is a partial overlap which we cannot represent.
Third stage just goes over the list and creates an appropriate vector of ipa_agg_jf_item structures out of it, of sourse only if there are any known constants to begin with.
|
static |
If STMT can be proved to be an assignment to the virtual method table pointer of ANALYZED_OBJ and the type associated with the new table identified, return the type. Otherwise return NULL_TREE.
References type_change_info::known_current_type, type_change_info::multiple_types_encountered, stmt_may_be_vtbl_ptr_store(), type(), and type_change_info::type_maybe_changed.
|
static |
Free stuff in PARMS_AINFO, assume there are PARAM_COUNT parameters.
|
static |
Extract the base, offset and MEM_REF expression from a statement ASSIGN if it looks like: iftmp.1_3 = &obj_2(D)->D.1762; The base of the MEM_REF must be a default definition SSA NAME of a parameter. Return NULL_TREE if it looks otherwise. If case of success, the whole MEM_REF expression is returned and the offset calculated from any handled components and the MEM_REF itself is stored into *OFFSET. The whole RHS stripped off the ADDR_EXPR is stored into *OBJ_P.
If this is a varying address, punt.
References detect_type_change(), gimple_bb(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_phi_num_args(), HOST_WIDE_INT, integer_zerop(), ipa_get_param_decl_index(), IPA_JF_UNKNOWN, last_stmt(), offset, single_pred(), single_pred_p(), and ipa_jump_func::type.
|
inlinestatic |
If RHS is an SSA_NAME and it is defined by a simple copy assign statement, return the rhs of its defining statement. Otherwise return RHS as it is.
References ao_ref_init_from_ptr_and_size(), build_int_cst(), get_ref_base_and_extent(), HOST_WIDE_INT, and ipa_known_agg_contents_list::size.
Return a heap allocated vector containing types of formal parameters of function type FNTYPE.
References NOT_BUILT_IN.
Referenced by ipa_free_all_structures_after_ipa_cp().
|
static |
Return true iff BASE_INDEX is in ADJUSTMENTS more than once.
References HOST_WIDE_INT_PRINT_DEC, ipa_agg_replacement_value::index, ipa_agg_replacement_value::next, ipa_agg_replacement_value::offset, print_generic_expr(), and ipa_agg_replacement_value::value.
|
static |
Analyze newly added function into callgraph.
Referenced by ipa_edge_duplication_hook().
void ipa_alloc_node_params | ( | ) |
Initialize the ipa_node_params structure associated with NODE to hold PARAM_COUNT parameters.
References count_formal_params(), symtab_node_base::decl, ipa_node_params::descriptors, and ipa_populate_param_decls().
|
static |
Analyze a call statement CALL whether and how it utilizes formal parameters of the caller (described by INFO). PARMS_AINFO is a pointer to a vector containing intermediate information about each formal parameter.
References symtab_node_base::decl, has_zero_uses(), ipa_set_param_used(), is_gimple_call(), and ssa_default_def().
|
static |
Analyze the CALL and examine uses of formal parameters of the caller NODE (described by INFO). PARMS_AINFO is a pointer to a vector containing intermediate information about each formal parameter. Currently it checks whether the call calls a pointer that is a formal parameter and if so, the parameter is marked with the called flag and an indirect call graph edge describing the call is created. This is very simple for ordinary pointers represented in SSA but not-so-nice when it comes to member pointers. The ugly part of this function does nothing more than trying to match the pattern of such a call. An example of such a pattern is the gimple dump below, the call is on the last line: <bb 2>: f$__delta_5 = f.__delta; f$__pfn_24 = f.__pfn; or <bb 2>: f$__delta_5 = MEM[(struct *)&f]; f$__pfn_24 = MEM[(struct *)&f + 4B]; and a few lines below: <bb 5> D.2496_3 = (int) f$__pfn_24; D.2497_4 = D.2496_3 & 1; if (D.2497_4 != 0) goto <bb 3>; else goto <bb 4>; <bb 6>: D.2500_7 = (unsigned int) f$__delta_5; D.2501_8 = &S + D.2500_7; D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8; D.2503_10 = *D.2502_9; D.2504_12 = f$__pfn_24 + -1; D.2505_13 = (unsigned int) D.2504_12; D.2506_14 = D.2503_10 + D.2505_13; D.2507_15 = *D.2506_14; iftmp.11_16 = (String:: *) D.2507_15; <bb 7>: # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)> D.2500_19 = (unsigned int) f$__delta_5; D.2508_20 = &S + D.2500_19; D.2493_21 = iftmp.11_1 (D.2508_20, 4); Such patterns are results of simple calls to a member pointer: int doprinting (int (MyString::* f)(int) const) { MyString S ("somestring"); return (S.*f)(4); } Moreover, the function also looks for called pointers loaded from aggregates passed by value or reference.
Now we need to try to match the complex pattern of calling a member pointer.
First, we need to check whether one of these is a load from a member pointer that is a parameter to this function.
Second, we need to check that the basic blocks are laid out in the way corresponding to the pattern.
Third, let's see that the branching is done depending on the least significant bit of the pfn.
void ipa_analyze_node | ( | ) |
Initialize the array describing properties of of formal parameters of NODE, analyze their uses and compute jump functions associated with actual arguments of calls from within NODE.
References ipa_jump_func::agg, ipa_ancestor_jf_data::agg_preserved, ipa_jump_func::jump_func_value::ancestor, ipa_agg_jump_function::by_ref, ipa_ancestor_jf_data::formal_id, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), IPA_JF_ANCESTOR, IPA_JF_UNKNOWN, ipa_agg_jump_function::items, ipa_jump_func::type, and ipa_jump_func::value.
Referenced by spread_undeadness().
|
static |
Scan the function body of NODE and inspect the uses of formal parameters. Store the findings in various structures of the associated ipa_node_params structure, such as parameter flags, notes etc. PARMS_AINFO is a pointer to a vector containing intermediate information about each formal parameter.
For SSA regs see if parameter is used. For non-SSA we compute the flag during modification analysis.
|
static |
Analyze the call statement STMT with respect to formal parameters (described in INFO) of caller given by NODE. Currently it only checks whether formal parameters are called. PARMS_AINFO is a pointer to a vector containing intermediate information about each formal parameter.
|
static |
Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the object referenced in the expression is a formal parameter of the caller (described by INFO), create a call note for the statement.
References get_base_address(), ipa_get_param_decl_index(), and ipa_set_param_used().
tree ipa_binfo_from_known_type_jfunc | ( | ) |
Extract the acual BINFO being described by JFUNC which must be a known type jump function.
Referenced by propagate_vals_accross_pass_through().
ipa_parm_adjustment_vec ipa_combine_adjustments | ( | ipa_parm_adjustment_vec | inner, |
ipa_parm_adjustment_vec | outer | ||
) |
Return adjustments that should have the same effect on function parameters and call arguments as if they were first changed according to adjustments in INNER and then by adjustments in OUTER.
FIXME: Create nonlocal value too.
|
static |
Compute jump functions for all edges - both direct and indirect - outgoing from NODE. Also count the actual arguments in the process.
We do not need to bother analyzing calls to unknown functions unless they may become known during lto/whopr.
|
static |
Compute jump function for all arguments of callsite CS and insert the information in the jump_functions array in the ipa_edge_args corresponding to this callsite.
Aggregate passed by value, check for pass-through, otherwise we will attempt to fill in aggregate contents later in this for cycle.
void ipa_dump_agg_replacement_values | ( | ) |
Dump the AV linked list.
void ipa_dump_param | ( | ) |
Return the declaration of Ith formal parameter of the function corresponding to INFO. Note there is no setter function as this array is built just once using ipa_initialize_node_params.
Referenced by ipa_node_duplication_hook(), and update_specialized_profile().
void ipa_dump_param_adjustments | ( | FILE * | file, |
ipa_parm_adjustment_vec | adjustments, | ||
tree | fndecl | ||
) |
Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human friendly way, assuming they are meant to be applied to FNDECL.
|
static |
Hook that is called by cgraph.c when an edge is duplicated.
This can happen during inlining, when a JFUNC can refer to a reference taken in a function up in the tree of inline clones. We need to find the duplicate that refers to our tree of inline clones.
References cgraph_add_edge_duplication_hook(), cgraph_add_edge_removal_hook(), cgraph_add_function_insertion_hook(), cgraph_add_node_duplication_hook(), cgraph_add_node_removal_hook(), ipa_add_new_function(), ipa_edge_removal_hook(), ipa_node_duplication_hook(), and ipa_node_removal_hook().
|
static |
Hook that is called by cgraph.c when an edge is removed.
During IPA-CP updating we can be called on not-yet analyzed clones.
References ipa_node_params::descriptors, ipa_check_create_node_params(), ipa_get_agg_replacements_for_node(), ipa_set_node_agg_value_chain(), ipa_node_params::ipcp_orig_node, ipa_node_params::lattices, memcpy(), ipa_agg_replacement_value::next, ipa_node_params::node_enqueued, and ipa_node_params::uses_analysis_done.
Referenced by ipa_edge_duplication_hook().
tree ipa_find_agg_cst_for_param | ( | struct ipa_agg_jump_function * | agg, |
HOST_WIDE_INT | offset, | ||
bool | by_ref | ||
) |
Retrieve value from aggregate jump function AGG for the given OFFSET or return NULL if there is not any. BY_REF specifies whether the value has to be passed by reference or by value.
Currently we do not have clobber values, return NULL for them once we do.
References ipa_jump_func::agg, cgraph_indirect_call_info::agg_contents, cgraph_indirect_call_info::by_ref, cgraph_edge::callee, cgraph_node_for_jfunc(), cgraph_edge::indirect_info, ipa_find_agg_cst_for_param(), IPA_JF_CONST, ipa_make_edge_direct_to_target(), ipa_value_from_jfunc(), cgraph_indirect_call_info::offset, try_decrement_rdesc_refcount(), and ipa_jump_func::type.
Referenced by ipa_find_agg_cst_for_param(), and set_hint_predicate().
void ipa_free_all_edge_args | ( | void | ) |
Free all ipa_edge structures.
References cgraph_edge::call_stmt, cgraph_edge::caller, cgraph_node_for_jfunc(), ipa_jump_func::jump_func_value::constant, ipa_cst_ref_desc::cs, ipa_clone_ref(), ipa_find_reference(), cgraph_edge::lto_stmt_uid, ipa_cst_ref_desc::next_duplicate, pool_alloc(), ipa_constant_data::rdesc, ipa_cst_ref_desc::refcount, ipa_ref::stmt, and ipa_jump_func::value.
void ipa_free_all_node_params | ( | void | ) |
Free all ipa_node_params structures.
void ipa_free_all_structures_after_iinln | ( | void | ) |
Free all ipa_node_params and all ipa_edge_args structures if they are no longer needed after indirect inlining.
References ipa_parm_adjustment::base, ipa_parm_adjustment::base_index, ipa_parm_adjustment::copy_param, and ipa_parm_adjustment::remove_param.
void ipa_free_all_structures_after_ipa_cp | ( | void | ) |
Free all ipa_node_params and all ipa_edge_args structures if they are no longer needed after ipa-cp.
References get_vector_of_formal_parm_types(), and tree_last().
void ipa_free_edge_args_substructures | ( | ) |
Frees all dynamically allocated structures that the argument info points to.
void ipa_free_node_params_substructures | ( | ) |
Frees all dynamically allocated structures that the param info points to.
Lattice values and their sources are deallocated with their alocation pool.
References ipa_jump_func::jump_func_value::constant, ipa_cst_ref_desc::cs, ipa_cst_ref_desc::next_duplicate, pool_alloc(), ipa_constant_data::rdesc, ipa_cst_ref_desc::refcount, and ipa_jump_func::value.
|
static |
Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated with NODE should prevent us from analyzing it for the purposes of IPA-CP.
References count.
|
static |
int ipa_get_param_decl_index | ( | ) |
Return index of the formal whose tree is PTREE in function which corresponds to INFO.
Referenced by get_ancestor_addr_info(), initialize_inline_failed(), ipa_analyze_virtual_call_uses(), ipa_load_from_parm_agg(), ipa_note_param_call(), and will_be_nonconstant_expr_predicate().
|
static |
Return index of the formal whose tree is PTREE in function which corresponds to INFO.
References ipa_node_params::descriptors.
Referenced by mark_modified().
|
static |
If STMT looks like a statement loading a value from a member pointer formal parameter, return that parameter and store the offset of the field to *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still might be clobbered). If USE_DELTA, then we look for a use of the delta field rather than the pfn.
Return a heap allocated vector containing formal parameters of FNDECL.
References build_distinct_type_copy().
Referenced by ipa_unregister_cgraph_hooks().
void ipa_initialize_node_params | ( | ) |
Initialize the ipa_node_params structure associated with NODE by counting the function parameters, creating the descriptors and populating their param_decls.
References ipa_known_type_data::base_type, ipa_get_ith_jump_func(), IPA_JF_KNOWN_TYPE, IPA_JF_UNKNOWN, ipa_jump_func::jump_func_value::known_type, print_generic_expr(), ipa_jump_func::type, type(), and ipa_jump_func::value.
tree ipa_intraprocedural_devirtualization | ( | ) |
Given a statement CALL which must be a GIMPLE_CALL calling an OBJ_TYPE_REF attempt a type-based devirtualization. If successful, return the target function declaration, otherwise return NULL.
|
static |
Returns true iff T is an SSA_NAME defined by a statement.
bool ipa_load_from_parm_agg | ( | struct ipa_node_params * | info, |
gimple | stmt, | ||
tree | op, | ||
int * | index_p, | ||
HOST_WIDE_INT * | offset_p, | ||
bool * | by_ref_p | ||
) |
Just like the previous function, just without the param_analysis_info pointer, for users outside of this file.
References ipa_node_params::descriptors, detect_type_change_ssa(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_single_p(), gimple_expr_code(), HOST_WIDE_INT, ipa_get_param_decl_index(), IPA_JF_UNKNOWN, ipa_set_jf_arith_pass_through(), ipa_set_jf_simple_pass_through(), is_gimple_ip_invariant(), load_from_unmodified_param(), offset, parm_ref_data_pass_through_p(), tcc_comparison, ipa_jump_func::type, and useless_type_conversion_p().
|
static |
Return true if we can prove that OP is a memory reference loading unmodified data from an aggregate passed as a parameter and if the aggregate is passed by reference, that the alias type of the load corresponds to the type of the formal parameter (so that we can rely on this type for TBAA in callers). INFO and PARMS_AINFO describe parameters of the current function (but the latter can be NULL), STMT is the load statement. If function returns true, *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset within the aggregate and whether it is a load from a value passed by reference respectively.
This branch catches situations where a pointer parameter is not a gimple register, for example: void hip7(S*) (struct S * p) { void (*<T2e4>) (struct S *) D.1867; struct S * p.1; <bb 2>: p.1_1 = p; D.1867_2 = p.1_1->f; D.1867_2 (); gdp = &p;
Referenced by ipa_prop_write_all_agg_replacement().
|
read |
If TARGET is an addr_expr of a function declaration, make it the destination of an indirect edge IE and return the edge. Otherwise, return NULL.
Member pointer call that goes through a VMT lookup.
Because may-edges are not explicitely represented and vtable may be external, we may create the first reference to the object in the unit.
We are better to ensure we can refer to it. In the case of static functions we are out of luck, since we already removed its body. In the case of public functions we may or may not introduce the reference.
We can not make edges to inline clones. It is bug that someone removed the cgraph node too early.
Referenced by ipa_find_agg_cst_for_param(), and safe_add().
void ipa_modify_call_arguments | ( | struct cgraph_edge * | cs, |
gimple | stmt, | ||
ipa_parm_adjustment_vec | adjustments | ||
) |
Modify actual arguments of a function call CS as indicated in ADJUSTMENTS. If this is a directly recursive call, CS must be NULL. Otherwise it must contain the corresponding call graph edge.
We create a new parameter out of the value of the old one, we can do the following kind of transformations: - A scalar passed by reference is converted to a scalar passed by value. (adj->by_ref is false and the type of the original actual argument is a pointer to a scalar). - A part of an aggregate is passed instead of the whole aggregate. The part can be passed either by value or by reference, this is determined by value of adj->by_ref. Moreover, the code below handles both situations when the original aggregate is passed by value (its type is not a pointer) and when it is passed by reference (it is a pointer to an aggregate). When the new argument is passed by reference (adj->by_ref is true) it must be a part of an aggregate and therefore we form it by simply taking the address of a reference inside the original aggregate.
Aggregate arguments can have non-invariant addresses.
References ipa_parm_adjustment::base, ipa_parm_adjustment::base_index, decl_debug_args_insert(), fold_convert_loc(), fold_convertible_p(), gimple_call_arg(), gimple_location(), gsi_insert_before(), GSI_SAME_STMT, unshare_expr(), useless_type_conversion_p(), vec_safe_iterate(), and vec_safe_push().
void ipa_modify_formal_parameters | ( | tree | fndecl, |
ipa_parm_adjustment_vec | adjustments, | ||
const char * | synth_parm_prefix | ||
) |
Modify the function declaration FNDECL and its type according to the plan in ADJUSTMENTS. It also sets base fields of individual adjustments structures to reflect the actual parameters being modified which are determined by the base_index field.
The following test is an ugly hack, some functions simply don't have any arguments in their type. This is probably a bug but well...
Use copy_node to preserve as much as possible from original type (debug info, attribute lists etc.) Exception is METHOD_TYPEs must have THIS argument. When we are asked to remove it, we need to build new FUNCTION_TYPE instead.
When signature changes, we need to clear builtin info.
This is a new type, not a copy of an old type. Need to reassociate variants. We can handle everything except the main variant lazily.
|
static |
Hook that is called by cgraph.c when a node is duplicated.
References ipa_dump_param(), ipa_get_controlled_uses(), and ipa_is_param_used().
Referenced by ipa_edge_duplication_hook().
|
static |
Hook that is called by cgraph.c when a node is removed.
During IPA-CP updating we can be called on not-yet analyze clones.
Referenced by ipa_edge_duplication_hook().
|
staticread |
Find the indirect call graph edge corresponding to STMT and mark it as a call to a parameter number PARAM_INDEX. NODE is the caller. Return the indirect call graph edge.
References ipa_get_param_decl_index().
|
static |
Populate the param_decl field in parameter DESCRIPTORS that correspond to NODE.
Referenced by ipa_alloc_node_params().
void ipa_print_all_jump_functions | ( | ) |
Print ipa_jump_func data structures of all nodes in the call graph to F.
void ipa_print_all_params | ( | ) |
Print ipa_tree_map data structures of all functions in the callgraph to F.
References nreverse().
void ipa_print_node_jump_functions | ( | ) |
Print the jump functions of all arguments on all call graph edges going from NODE to file F.
|
static |
Print the jump functions associated with call graph edge CS to file F.
void ipa_print_node_params | ( | ) |
Print ipa_tree_map data structures of all functions in the callgraph to F.
void ipa_prop_read_all_agg_replacement | ( | void | ) |
Read IPA-CP aggregate replacements.
Referenced by identify_dead_nodes().
void ipa_prop_read_jump_functions | ( | void | ) |
Read ipcp jump functions.
|
static |
Read section in file FILE_DATA of length LEN with data DATA.
void ipa_prop_write_all_agg_replacement | ( | void | ) |
Write all aggregate replacement for nodes in set.
References ipa_agg_replacement_value::by_ref, gimple_assign_load_p(), gimple_assign_rhs1(), gsi_stmt(), handled_component_p(), HOST_WIDE_INT, ipa_agg_replacement_value::index, ipa_load_from_parm_agg_1(), is_gimple_ip_invariant(), is_gimple_reg_type(), ipa_agg_replacement_value::next, ipa_agg_replacement_value::offset, offset, and ipa_agg_replacement_value::value.
Referenced by identify_dead_nodes().
void ipa_prop_write_jump_functions | ( | void | ) |
Write jump functions for nodes in SET.
Process all of the functions.
bool ipa_propagate_indirect_call_infos | ( | struct cgraph_edge * | cs, |
vec< cgraph_edge_p > * | new_edges | ||
) |
Update jump functions and call note functions on inlining the call site CS. CS is expected to lead to a node already cloned by cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were + created.
Do nothing if the preparation phase has not been carried out yet (i.e. during early inlining).
|
static |
Read in parts of cgraph_indirect_call_info corresponding to CS that are relevant to indirect inlining from IB.
|
static |
Read in jump function JUMP_FUNC from IB.
|
static |
Stream in NODE info from IB.
References ipa_check_create_edge_args(), and ipa_check_create_node_params().
void ipa_register_cgraph_hooks | ( | void | ) |
Register our cgraph hooks if they are not already there.
Referenced by spread_undeadness().
|
static |
Set JFUNC to be an ancestor jump function.
References HOST_WIDE_INT, type_change_info::known_current_type, type_change_info::multiple_types_encountered, type_change_info::object, type_change_info::offset, and type_change_info::type_maybe_changed.
|
static |
Set JFUNC to be an arithmetic pass through jump function.
References ipa_known_type_data::base_type, ipa_known_type_data::component_type, get_binfo_at_offset(), ipa_jump_func::jump_func_value::known_type, ipa_known_type_data::offset, and ipa_jump_func::value.
Referenced by ipa_load_from_parm_agg(), and update_jump_functions_after_inlining().
|
static |
Set JFUNC to be a constant jmp function.
|
static |
Set JFUNC to be a copy of another jmp (to be used by jump function combination code). The two functions will share their rdesc.
Referenced by combine_known_type_and_ancestor_jfs().
|
static |
Set JFUNC to be a known type jump function.
References ipa_jump_func::jump_func_value::constant, IPA_JF_CONST, ipa_jump_func::type, unshare_expr(), unshare_expr_without_location(), ipa_constant_data::value, and ipa_jump_func::value.
Referenced by combine_known_type_and_ancestor_jfs().
|
static |
Set JFUNC to be a simple pass-through jump function.
References ipa_ancestor_jf_data::agg_preserved, ipa_jump_func::jump_func_value::ancestor, ipa_ancestor_jf_data::formal_id, IPA_JF_ANCESTOR, ipa_ancestor_jf_data::offset, offset, ipa_ancestor_jf_data::type, ipa_jump_func::type, type(), ipa_ancestor_jf_data::type_preserved, and ipa_jump_func::value.
Referenced by ipa_load_from_parm_agg(), and update_jump_functions_after_inlining().
void ipa_set_node_agg_value_chain | ( | struct cgraph_node * | node, |
struct ipa_agg_replacement_value * | aggvals | ||
) |
Set the aggregate replacements of NODE to be AGGVALS.
Referenced by ipa_edge_removal_hook().
|
static |
Unregister our cgraph hooks if they are not already there.
References ipa_get_vector_of_formal_parms(), and len.
void ipa_update_after_lto_read | ( | void | ) |
After merging units, we can get mismatch in argument counts. Also decl merging might've rendered parameter lists obsolete. Also compute called_with_variable_arg info.
|
static |
Stream out parts of cgraph_indirect_call_info corresponding to CS that are relevant to indirect inlining to OB.
|
static |
Stream out jump function JUMP_FUNC to OB.
|
static |
Stream out NODE info to OB.
unsigned int ipcp_transform_function | ( | ) |
Function body transformation phase.
V_C_E can do things like convert an array of integers to one bigger integer and similar things we do not handle below.
|
staticread |
If JFUNC has a reference description with refcount different from IPA_UNDESCRIBED_USE, return the reference description, otherwise return NULL. JFUNC must be a constant jump function.
|
static |
If STMT is an assignment that loads a value from an parameter declaration, return the index of the parameter in ipa_node_params which has not been modified. Otherwise return -1.
References ao_ref_init_from_ptr_and_size(), gimple_vuse(), mark_modified(), param_analysis_info::pt_modified, param_analysis_info::pt_visited_statements, and walk_aliased_vdefs().
Referenced by ipa_load_from_parm_agg().
Callback of walk_aliased_vdefs. Flags that it has been invoked to the boolean variable pointed to by DATA.
References gimple_assign_rhs1(), gimple_assign_single_p(), and ipa_get_param_decl_index_1().
Referenced by load_from_unmodified_param().
|
static |
Return true if a load from a formal parameter PARM_LOAD is known to retrieve a value known not to be modified in this function before reaching the statement STMT. PARM_AINFO is a pointer to a structure containing temporary information about the parameter.
We can cache visited statements only when parm_ainfo is available and when we are looking at a naked load of the whole parameter.
|
static |
Return true if the data pointed to by PARM is known to be unmodified in this function before reaching call statement CALL into which it is passed. PARM_AINFO is a pointer to a structure containing temporary information about PARM.
It's unnecessary to calculate anything about memory contnets for a const function because it is not goin to use it. But do not cache the result either. Also, no such calculations for non-pointers.
Referenced by ipa_load_from_parm_agg().
|
static |
Return true if memory reference REF loads data that are known to be unmodified in this function before reaching statement STMT. PARM_AINFO, if non-NULL, is a pointer to a structure containing temporary information about PARM.
References get_ref_base_and_extent(), and HOST_WIDE_INT.
|
static |
Propagate number of controlled users from CS->caleee to the new root of the tree of inlined nodes.
References cgraph_edge::callee, changed, and propagate_info_to_inlined_callees().
|
static |
Recursively traverse subtree of NODE (including node) made of inlined cgraph_edges when CS has been inlined and invoke update_indirect_edges_after_inlining on all nodes and update_jump_functions_after_inlining on all non-inlined edges that lead out of this subtree. Newly discovered indirect edges will be added to *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were created.
Referenced by propagate_controlled_uses().
|
static |
Stream in the aggregate value replacement chain for NODE from IB.
|
static |
Read replacements section in file FILE_DATA of length LEN with data DATA.
References dump_file, fold_convertible_p(), print_generic_expr(), and ipa_agg_replacement_value::value.
|
static |
Remove a reference to SYMBOL from the list of references of a node given by reference description RDESC. Return true if the reference has been successfully found and removed.
|
static |
Return true if STMT can modify a virtual method table pointer. This function makes special assumptions about both constructors and destructors which are all the functions that are allowed to alter the VMT pointers. It assumes that destructors begin with assignment into all VMT pointers and that constructors essentially look in the following way: 1) The very first thing they do is that they call constructors of ancestor sub-objects that have them. 2) Then VMT pointers of this and all its ancestors is set to new values corresponding to the type corresponding to the constructor. 3) Only afterwards, other stuff such as constructor of member sub-objects and the code written by the user is run. Only this may include calling virtual functions, directly or indirectly. There is no way to call a constructor of an ancestor sub-object in any other way. This means that we do not have to care whether constructors get the correct type information because they will always change it (in fact, if we define the type to be given by the VMT pointer, it is undefined). The most important fact to derive from the above is that if, for some statement in the section 3, we try to detect whether the dynamic type has changed, we can safely ignore all calls as we examine the function body backwards until we reach statements in section 2 because these calls cannot be ancestor constructors or destructors (if the input is not bogus) and so do not change the dynamic type (this holds true only for automatically allocated objects but at the moment we devirtualize only these). We then must detect that statements in section 2 change the dynamic type and can try to derive the new type. That is enough and we can stop, we will never see the calls into constructors of sub-objects in this code. Therefore we can safely ignore all call statements that we traverse.
In the future we might want to use get_base_ref_and_offset to find if there is a field corresponding to the offset and if so, proceed almost like if it was a component ref.
Referenced by extr_type_from_vtbl_ptr_store().
|
static |
If JFUNC is a constant jump function with a usable rdesc, decrement its refcount and if it hits zero, remove reference to SYMBOL from the caller of the edge specified in the rdesc. Return false if either the symbol or the reference could not be found, otherwise return true.
References cgraph_edge::caller, cgraph_node::global, cgraph_node::indirect_calls, cgraph_edge::indirect_info, cgraph_global_info::inlined_to, ipa_check_create_edge_args(), cgraph_edge::next_callee, and cgraph_indirect_call_info::param_index.
Referenced by ipa_find_agg_cst_for_param().
|
staticread |
Try to find a destination for indirect edge IE that corresponds to a simple call or a call of a member function pointer and where the destination is a pointer formal parameter described by jump function JFUNC. If it can be determined, return the newly direct edge, otherwise return NULL. NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.
References cgraph_indirect_call_info::param_index.
|
staticread |
Try to find a destination for indirect edge IE that corresponds to a virtual call based on a formal parameter which is described by jump function JFUNC and if it can be determined, make it direct and return the direct edge. Otherwise, return NULL. NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.
References cgraph_indirect_call_info::agg_contents, ipa_get_jf_pass_through_agg_preserved(), ipa_get_jf_pass_through_formal_id(), and cgraph_indirect_call_info::param_index.
|
static |
Inspect the given TYPE and return true iff it has the same structure (the same number of fields of the same types) as a C++ member pointer. If METHOD_PTR and DELTA are non-NULL, store the trees representing the corresponding fields there.
References ao_ref_init_from_ptr_and_size(), host_integerp(), HOST_WIDE_INT, and tree_low_cst().
|
static |
Update the param called notes associated with NODE when CS is being inlined, assuming NODE is (potentially indirectly) inlined into CS->callee. Moreover, if the callee is discovered to be constant, create a new cgraph edge for it. Newly discovered indirect edges will be added to *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were created.
We must check range due to calls with variable number of arguments:
If speculation was removed, then we need to do nothing.
Either we can find a destination for this edge now or never.
|
static |
Update the jump functions associated with call graph edge E when the call graph edge CS is being inlined, assuming that E->caller is already (possibly indirectly) inlined into CS->callee and that E has not been inlined.
Variable number of arguments can cause havoc if we try to access one that does not exist in the inlined edge. So make sure we don't.
Currently we do not produce clobber aggregate jump functions, replace with merging when we do.
We must check range due to calls with variable number of arguments and we cannot combine jump functions with operations.
Currently we do not produce clobber aggregate jump functions, replace with merging when we do.
References ipa_get_jf_pass_through_agg_preserved(), ipa_get_jf_pass_through_formal_id(), ipa_get_jf_pass_through_operand(), ipa_get_jf_pass_through_operation(), ipa_get_jf_pass_through_type_preserved(), ipa_set_jf_arith_pass_through(), and ipa_set_jf_simple_pass_through().
Callback of walk_stmt_load_store_addr_ops for the visit_load. If OP is a parameter declaration, mark it as used in the info structure passed in DATA.
void write_agg_replacement_chain | ( | ) |
References ipa_agg_replacement_value::index.
|
static |
|
static |
Holders of ipa cgraph hooks:
|
static |
vec<ipa_edge_args_t, va_gc>* ipa_edge_args_vector |
Vector where the parameter infos are actually stored.
vec<ipa_agg_replacement_value_p, va_gc>* ipa_node_agg_replacements |
Vector of known aggregate values in cloned nodes.
vec<ipa_node_params_t> ipa_node_params_vector |
Vector where the parameter infos are actually stored.
Referenced by estimate_ipcp_clone_size_and_time(), and inline_node_removal_hook().
|
static |
Allocation pool for reference descriptions.
|
static |
|
static |