diff options
author | Martin Jambor <mjambor@suse.cz> | 2017-01-09 19:26:37 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2017-01-09 19:26:37 +0100 |
commit | a5e14a42da5eba45cc6528e678ba7e191b9c6cd8 (patch) | |
tree | 782daa89542faa2fad17e82610e4d4d431bca277 /gcc/ipa-cp.c | |
parent | a7765de8ef7653d7e899b24ed7bb3819e5f90f29 (diff) | |
download | gcc-a5e14a42da5eba45cc6528e678ba7e191b9c6cd8.zip gcc-a5e14a42da5eba45cc6528e678ba7e191b9c6cd8.tar.gz gcc-a5e14a42da5eba45cc6528e678ba7e191b9c6cd8.tar.bz2 |
[PR 78365] Prudent type handling in IPA VR-prop
2017-01-09 Martin Jambor <mjambor@suse.cz>
PR ipa/78365
PR ipa/78599
* ipa-prop.h (ipa_jump_func): Swap positions of vr_known and m_vr.
* ipa-cp.c (ipa_vr_operation_and_type_effects): New function.
(propagate_vr_accross_jump_function): Use the above function for all
value range computations for pass-through jump functions and type
converasion from explicit value range values.
(ipcp_propagate_stage): Do not attempt to deduce types of formal
parameters from TYPE_ARG_TYPES.
* ipa-prop.c (ipa_write_jump_function): Remove trailing whitespace.
(ipa_write_node_info): Stream type of the actual argument.
(ipa_read_node_info): Likewise. Also remove trailing whitespace.
testsuite/
* gcc.dg/torture/pr78365.c: New test.
From-SVN: r244232
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r-- | gcc/ipa-cp.c | 71 |
1 files changed, 35 insertions, 36 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 82bf350..9cc9037 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1837,6 +1837,23 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx, return dest_lattice->set_to_bottom (); } +/* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to + DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if + the result is a range or an anti-range. */ + +static bool +ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr, + enum tree_code operation, + tree dst_type, tree src_type) +{ + memset (dst_vr, 0, sizeof (*dst_vr)); + extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type); + if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE) + return true; + else + return false; +} + /* Propagate value range across jump function JFUNC that is associated with edge CS with param of callee of PARAM_TYPE and update DEST_PLATS accordingly. */ @@ -1846,7 +1863,6 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, struct ipcp_param_lattices *dest_plats, tree param_type) { - struct ipcp_param_lattices *src_lats; ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range; if (dest_lat->bottom_p ()) @@ -1859,31 +1875,23 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, if (jfunc->type == IPA_JF_PASS_THROUGH) { - struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); - int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); - src_lats = ipa_get_parm_lattices (caller_info, src_idx); + enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); - if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) - return dest_lat->meet_with (src_lats->m_value_range); - else if (param_type - && (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) - == tcc_unary)) + if (TREE_CODE_CLASS (operation) == tcc_unary) { - value_range vr; - memset (&vr, 0, sizeof (vr)); + struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); + int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); tree operand_type = ipa_get_type (caller_info, src_idx); - enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); + struct ipcp_param_lattices *src_lats + = ipa_get_parm_lattices (caller_info, src_idx); if (src_lats->m_value_range.bottom_p ()) return dest_lat->set_to_bottom (); - - extract_range_from_unary_expr (&vr, - operation, - param_type, - &src_lats->m_value_range.m_vr, - operand_type); - if (vr.type == VR_RANGE - || vr.type == VR_ANTI_RANGE) + value_range vr; + if (ipa_vr_operation_and_type_effects (&vr, + &src_lats->m_value_range.m_vr, + operation, param_type, + operand_type)) return dest_lat->meet_with (&vr); } } @@ -1903,8 +1911,12 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, } } - if (jfunc->vr_known) - return dest_lat->meet_with (&jfunc->m_vr); + value_range vr; + if (jfunc->vr_known + && ipa_vr_operation_and_type_effects (&vr, &jfunc->m_vr, NOP_EXPR, + param_type, + TREE_TYPE (jfunc->m_vr.min))) + return dest_lat->meet_with (&vr); else return dest_lat->set_to_bottom (); } @@ -2244,7 +2256,7 @@ propagate_constants_across_call (struct cgraph_edge *cs) { struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i); struct ipcp_param_lattices *dest_plats; - tree param_type = ipa_get_callee_param_type (cs, i); + tree param_type = ipa_get_type (callee_info, i); dest_plats = ipa_get_parm_lattices (callee_info, i); if (availability == AVAIL_INTERPOSABLE) @@ -3230,19 +3242,6 @@ ipcp_propagate_stage (struct ipa_topo_info *topo) { struct ipa_node_params *info = IPA_NODE_REF (node); - /* In LTO we do not have PARM_DECLs but we would still like to be able to - look at types of parameters. */ - if (in_lto_p) - { - tree t = TYPE_ARG_TYPES (TREE_TYPE (node->decl)); - for (int k = 0; k < ipa_get_param_count (info) && t; k++) - { - gcc_assert (t != void_list_node); - info->descriptors[k].decl_or_type = TREE_VALUE (t); - t = t ? TREE_CHAIN (t) : NULL; - } - } - determine_versionability (node, info); if (node->has_gimple_body_p ()) { |