diff options
author | Feng Xue <fxue@os.amperecomputing.com> | 2019-11-14 03:19:15 +0000 |
---|---|---|
committer | Feng Xue <fxue@gcc.gnu.org> | 2019-11-14 03:19:15 +0000 |
commit | eb270950acbae6f70e3487a6e63a26c1294656b3 (patch) | |
tree | d64f761c523baf3052aaaff96fd28ca6a47d6aaf /gcc/ipa-prop.h | |
parent | 3e7cf2e6c0ee30b83aa158b7bd2b2eb9a686c1c3 (diff) | |
download | gcc-eb270950acbae6f70e3487a6e63a26c1294656b3.zip gcc-eb270950acbae6f70e3487a6e63a26c1294656b3.tar.gz gcc-eb270950acbae6f70e3487a6e63a26c1294656b3.tar.bz2 |
Support extended aggregate jump function in ipa-cp
2019-11-14 Feng Xue <fxue@os.amperecomputing.com>
PR ipa/91682
* ipa-prop.h (jump_func_type): New value IPA_JF_LOAD_AGG.
(ipa_load_agg_data, ipa_agg_value, ipa_agg_value_set): New structs.
(ipa_agg_jf_item): Add new field jftype and type, redefine field value.
(ipa_agg_jump_function): Remove member function equal_to.
(ipa_agg_jump_function_p): Remove typedef.
(ipa_copy_agg_values, ipa_release_agg_values): New functions.
* ipa-prop.c (ipa_print_node_jump_functions_for_edge): Dump
information for aggregate jump function.
(get_ssa_def_if_simple_copy): Add new parameter rhs_stmt to
record last definition statement.
(load_from_unmodified_param_or_agg): New function.
(ipa_known_agg_contents_list): Add new field type and value, remove
field constant.
(build_agg_jump_func_from_list): Rename parameter const_count to
value_count, build aggregate jump function from ipa_load_agg_data.
(analyze_agg_content_value): New function.
(extract_mem_content): Analyze memory store assignment to prepare
information for aggregate jump function generation.
(determine_known_aggregate_parts): Add new parameter fbi, remove
parameter aa_walk_budeget_p.
(update_jump_functions_after_inlining): Update aggregate jump function.
(ipa_find_agg_cst_for_param): Change type of parameter agg.
(try_make_edge_direct_simple_call): Add new parameter new_root.
(try_make_edge_direct_virtual_call): Add new parameter new_root and
new_root_info.
(update_indirect_edges_after_inlining): Pass new argument to
try_make_edge_direct_simple_call and try_make_edge_direct_virtual_call.
(ipa_write_jump_function): Write aggregate jump function to file.
(ipa_read_jump_function): Read aggregate jump function from file.
(ipa_agg_value::equal_to): Migrate from ipa_agg_jf_item::equal_to.
* ipa-cp.c (ipa_get_jf_arith_result): New function.
(ipa_agg_value_from_node): Likewise.
(ipa_agg_value_set_from_jfunc): Likewise.
(propagate_vals_across_arith_jfunc): Likewise.
(propagate_aggregate_lattice): Likewise.
(ipa_get_jf_pass_through_result): Call ipa_get_jf_arith_result.
(propagate_vals_across_pass_through): Call
propagate_vals_across_arith_jfunc.
(get_clone_agg_value): Move forward.
(propagate_aggs_across_jump_function): Handle value propagation for
aggregate jump function.
(agg_jmp_p_vec_for_t_vec): Remove.
(context_independent_aggregate_values): Replace vec<ipa_agg_jf_item>
with vec<ipa_agg_value>.
(copy_plats_to_inter, intersect_with_plats): Likewise.
(agg_replacements_to_vector, intersect_with_agg_replacements): Likewise.
(intersect_aggregate_with_edge): Likewise.
(find_aggregate_values_for_callers_subset): Likewise.
(cgraph_edge_brings_all_agg_vals_for_node): Likewise.
(estimate_local_effects): Replace vec<ipa_agg_jump_function> and
vec<ipa_agg_jump_function_p> with vec<ipa_agg_value_set>.
(gather_context_independent_values): Likewise.
(perform_estimation_of_a_value, decide_whether_version_node): Likewise.
* ipa-fnsummary.c (evaluate_conditions_for_known_args): Replace
vec<ipa_agg_jump_function_p> with vec<ipa_agg_value_set>.
(evaluate_properties_for_edge): Likewise.
(estimate_edge_devirt_benefit): Likewise.
(estimate_edge_size_and_time): Likewise.
(estimate_calls_size_and_time): Likewise.
(ipa_call_context::ipa_call_context): Likewise.
(estimate_ipcp_clone_size_and_time): Likewise.
* ipa-fnsummary.h (ipa_call_context): Replace
vec<ipa_agg_jump_function_p> with vec<ipa_agg_value_set>.
* ipa-inline-analysis.c (do_estimate_edge_time): Replace
vec<ipa_agg_jump_function_p> with vec<ipa_agg_value_set>.
(do_estimate_edge_size): Likewise.
(do_estimate_edge_hints): Likewise.
2019-11-14 Feng Xue <fxue@os.amperecomputing.com>
PR ipa/91682
* gcc.dg/ipa/ipcp-agg-10.c: Change dg-scan string.
* gcc.dg/ipa/ipcp-agg-11.c: New test.
From-SVN: r278193
Diffstat (limited to 'gcc/ipa-prop.h')
-rw-r--r-- | gcc/ipa-prop.h | 182 |
1 files changed, 148 insertions, 34 deletions
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 3422cb2..7eb96a0 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -39,6 +39,15 @@ along with GCC; see the file COPYING3. If not see argument. Unknown - neither of the above. + IPA_JF_LOAD_AGG is a compound pass-through jump function, in which primary + operation on formal parameter is memory dereference that loads a value from + a part of an aggregate, which is represented or pointed to by the formal + parameter. Moreover, an additional unary/binary operation can be applied on + the loaded value, and final result is passed as actual argument of callee + (e.g. *(param_1(D) + 4) op 24 ). It is meant to describe usage of aggregate + parameter or by-reference parameter referenced in argument passing, commonly + found in C++ and Fortran. + IPA_JF_ANCESTOR is a special pass-through jump function, which means that the result is an address of a part of the object pointed to by the formal parameter to which the function refers. It is mainly intended to represent @@ -60,6 +69,7 @@ enum jump_func_type IPA_JF_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */ IPA_JF_CONST, /* represented by field costant */ IPA_JF_PASS_THROUGH, /* represented by field pass_through */ + IPA_JF_LOAD_AGG, /* represented by field load_agg */ IPA_JF_ANCESTOR /* represented by field ancestor */ }; @@ -97,6 +107,26 @@ struct GTY(()) ipa_pass_through_data unsigned agg_preserved : 1; }; +/* Structure holding data required to describe a load-value-from-aggregate + jump function. */ + +struct GTY(()) ipa_load_agg_data +{ + /* Inherit from pass through jump function, describing unary/binary + operation on the value loaded from aggregate that is represented or + pointed to by the formal parameter, specified by formal_id in this + pass_through jump function data structure. */ + struct ipa_pass_through_data pass_through; + /* Type of the value loaded from the aggregate. */ + tree type; + /* Offset at which the value is located within the aggregate. */ + HOST_WIDE_INT offset; + /* True if loaded by reference (the aggregate is pointed to by the formal + parameter) or false if loaded by value (the aggregate is represented + by the formal parameter). */ + bool by_ref; +}; + /* Structure holding data required to describe an ancestor pass-through jump function. */ @@ -110,58 +140,139 @@ struct GTY(()) ipa_ancestor_jf_data unsigned agg_preserved : 1; }; -/* An element in an aggegate part of a jump function describing a known value - at a given offset. When it is part of a pass-through jump function with - agg_preserved set or an ancestor jump function with agg_preserved set, all - unlisted positions are assumed to be preserved but the value can be a type - node, which means that the particular piece (starting at offset and having - the size of the type) is clobbered with an unknown value. When - agg_preserved is false or the type of the containing jump function is - different, all unlisted parts are assumed to be unknown and all values must - fulfill is_gimple_ip_invariant. */ +/* A jump function for an aggregate part at a given offset, which describes how + it content value is generated. All unlisted positions are assumed to have a + value defined in an unknown way. */ struct GTY(()) ipa_agg_jf_item { - /* The offset at which the known value is located within the aggregate. */ + /* The offset for the aggregate part. */ HOST_WIDE_INT offset; - /* The known constant or type if this is a clobber. */ - tree value; + /* Data type of the aggregate part. */ + tree type; - /* Return true if OTHER describes same agg item. */ - bool equal_to (const ipa_agg_jf_item &other); -}; + /* Jump function type. */ + enum jump_func_type jftype; + /* Represents a value of jump function. constant represents the actual constant + in constant jump function content. pass_through is used only in simple pass + through jump function context. load_agg is for load-value-from-aggregate + jump function context. */ + union jump_func_agg_value + { + tree GTY ((tag ("IPA_JF_CONST"))) constant; + struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through; + struct ipa_load_agg_data GTY ((tag ("IPA_JF_LOAD_AGG"))) load_agg; + } GTY ((desc ("%1.jftype"))) value; +}; -/* Aggregate jump function - i.e. description of contents of aggregates passed - either by reference or value. */ +/* Jump functions describing a set of aggregate contents. */ struct GTY(()) ipa_agg_jump_function { - /* Description of the individual items. */ + /* Description of the individual jump function item. */ vec<ipa_agg_jf_item, va_gc> *items; - /* True if the data was passed by reference (as opposed to by value). */ + /* True if the data was passed by reference (as opposed to by value). */ bool by_ref; +}; + +/* An element in an aggregate part describing a known value at a given offset. + All unlisted positions are assumed to be unknown and all listed values must + fulfill is_gimple_ip_invariant. */ + +struct ipa_agg_value +{ + /* The offset at which the known value is located within the aggregate. */ + HOST_WIDE_INT offset; - /* Return true if OTHER describes same agg items. */ - bool equal_to (const ipa_agg_jump_function &other) + /* The known constant. */ + tree value; + + /* Return true if OTHER describes same agg value. */ + bool equal_to (const ipa_agg_value &other); +}; + +/* Structure describing a set of known offset/value for aggregate. */ + +struct ipa_agg_value_set +{ + /* Description of the individual item. */ + vec<ipa_agg_value> items; + /* True if the data was passed by reference (as opposed to by value). */ + bool by_ref; + + /* Return true if OTHER describes same agg values. */ + bool equal_to (const ipa_agg_value_set &other) { if (by_ref != other.by_ref) return false; - if (items != NULL && other.items == NULL) - return false; - if (!items) - return other.items == NULL; - if (items->length () != other.items->length ()) + if (items.length () != other.items.length ()) return false; - for (unsigned int i = 0; i < items->length (); i++) - if (!(*items)[i].equal_to ((*other.items)[i])) + for (unsigned int i = 0; i < items.length (); i++) + if (!items[i].equal_to (other.items[i])) return false; return true; } + + /* Return true if there is any value for aggregate. */ + bool is_empty () const + { + return items.is_empty (); + } + + ipa_agg_value_set copy () const + { + ipa_agg_value_set new_copy; + + new_copy.items = items.copy (); + new_copy.by_ref = by_ref; + + return new_copy; + } + + void release () + { + items.release (); + } }; -typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p; +/* Return copy of a vec<ipa_agg_value_set>. */ + +static inline vec<ipa_agg_value_set> +ipa_copy_agg_values (const vec<ipa_agg_value_set> &aggs) +{ + vec<ipa_agg_value_set> aggs_copy = vNULL; + + if (!aggs.is_empty ()) + { + ipa_agg_value_set *agg; + int i; + + aggs_copy.reserve_exact (aggs.length ()); + + FOR_EACH_VEC_ELT (aggs, i, agg) + aggs_copy.quick_push (agg->copy ()); + } + + return aggs_copy; +} + +/* For vec<ipa_agg_value_set>, DO NOT call release(), use below function + instead. Because ipa_agg_value_set contains a field of vector type, we + should release this child vector in each element before reclaiming the + whole vector. */ + +static inline void +ipa_release_agg_values (vec<ipa_agg_value_set> &aggs) +{ + ipa_agg_value_set *agg; + int i; + + FOR_EACH_VEC_ELT (aggs, i, agg) + agg->release (); + aggs.release (); +} /* Information about zero/non-zero bits. */ class GTY(()) ipa_bits @@ -193,8 +304,8 @@ public: types of jump functions supported. */ struct GTY (()) ipa_jump_func { - /* Aggregate contants description. See struct ipa_agg_jump_function and its - description. */ + /* Aggregate jump function description. See struct ipa_agg_jump_function + and its description. */ struct ipa_agg_jump_function agg; /* Information about zero/non-zero bits. The pointed to structure is shared @@ -857,9 +968,9 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, /* Indirect edge and binfo processing. */ tree ipa_get_indirect_edge_target (struct cgraph_edge *ie, - vec<tree> , + vec<tree>, vec<ipa_polymorphic_call_context>, - vec<ipa_agg_jump_function_p>, + vec<ipa_agg_value_set>, bool *); struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree, bool speculative = false); @@ -872,7 +983,7 @@ ipa_bits *ipa_get_ipa_bits_for_value (const widest_int &value, void ipa_analyze_node (struct cgraph_node *); /* Aggregate jump function related functions. */ -tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg, tree scalar, +tree ipa_find_agg_cst_for_param (struct ipa_agg_value_set *agg, tree scalar, HOST_WIDE_INT offset, bool by_ref, bool *from_global_constant = NULL); bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi, @@ -918,6 +1029,9 @@ ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *, cgraph_edge *, int, ipa_jump_func *); +ipa_agg_value_set ipa_agg_value_set_from_jfunc (ipa_node_params *, + cgraph_node *, + ipa_agg_jump_function *); void ipa_dump_param (FILE *, class ipa_node_params *info, int i); void ipa_release_body_info (struct ipa_func_body_info *); tree ipa_get_callee_param_type (struct cgraph_edge *e, int i); |