Hi, currently ipa_value_range_from_jfunc and propagate_vr_across_jump_function contain similar but not same code for dealing with pass-through jump functions. This patch puts these common bits into one function which can also handle comparison operations.
Bootstrapped and tested on x86_64-linux, the whole patch series has additionally passed LTO and profiled-LTO bootstrap on the same platform and a bootstrap and testsuite on ppc64-linux. Aarch64-linux bootstrap and testing is in progress. OK for master is that passes too? Thanks, Martin gcc/ChangeLog: 2024-11-01 Martin Jambor <mjam...@suse.cz> PR ipa/114985 * ipa-cp.cc (ipa_vr_intersect_with_arith_jfunc): New function. (ipa_value_range_from_jfunc): Move the common functionality to the above new function, adjust the rest so that it works with it well. (propagate_vr_across_jump_function): Likewise. --- gcc/ipa-cp.cc | 181 +++++++++++++++++++------------------------------- 1 file changed, 67 insertions(+), 114 deletions(-) diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index 212d9ccbbfe..fa4f0feeb8d 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -1682,6 +1682,55 @@ ipa_vr_operation_and_type_effects (vrange &dst_vr, dst_type, src_type); } +/* Given a PASS_THROUGH jump function JFUNC that takes as its source SRC_VR of + SRC_TYPE and the result needs to be DST_TYPE, if any value range information + can be deduced at all, intersect VR with it. */ + +static void +ipa_vr_intersect_with_arith_jfunc (vrange &vr, + ipa_jump_func *jfunc, + const value_range &src_vr, + tree src_type, + tree dst_type) +{ + if (src_vr.undefined_p () || src_vr.varying_p ()) + return; + + enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); + if (TREE_CODE_CLASS (operation) == tcc_unary) + { + value_range tmp_res (dst_type); + if (ipa_vr_operation_and_type_effects (tmp_res, src_vr, operation, + dst_type, src_type)) + vr.intersect (tmp_res); + return; + } + + tree operand = ipa_get_jf_pass_through_operand (jfunc); + range_op_handler handler (operation); + if (!handler) + return; + value_range op_vr (TREE_TYPE (operand)); + ipa_range_set_and_normalize (op_vr, operand); + + tree operation_type; + if (TREE_CODE_CLASS (operation) == tcc_comparison) + operation_type = boolean_type_node; + else + operation_type = src_type; + + value_range op_res (dst_type); + if (!ipa_vr_supported_type_p (operation_type) + || !handler.operand_check_p (operation_type, src_type, op_vr.type ()) + || !handler.fold_range (op_res, operation_type, src_vr, op_vr)) + return; + + value_range tmp_res (dst_type); + if (ipa_vr_operation_and_type_effects (tmp_res, op_res, NOP_EXPR, dst_type, + operation_type)) + vr.intersect (tmp_res); +} + /* Determine range of JFUNC given that INFO describes the caller node or the one it is inlined to, CS is the call graph edge corresponding to JFUNC and PARM_TYPE of the parameter. */ @@ -1691,18 +1740,18 @@ ipa_value_range_from_jfunc (vrange &vr, ipa_node_params *info, cgraph_edge *cs, ipa_jump_func *jfunc, tree parm_type) { - vr.set_undefined (); + vr.set_varying (parm_type); - if (jfunc->m_vr) + if (jfunc->m_vr && jfunc->m_vr->known_p ()) ipa_vr_operation_and_type_effects (vr, *jfunc->m_vr, NOP_EXPR, parm_type, jfunc->m_vr->type ()); if (vr.singleton_p ()) return; + if (jfunc->type == IPA_JF_PASS_THROUGH) { - int idx; ipcp_transformation *sum = ipcp_get_transformation_summary (cs->caller->inlined_to ? cs->caller->inlined_to @@ -1710,54 +1759,15 @@ ipa_value_range_from_jfunc (vrange &vr, if (!sum || !sum->m_vr) return; - idx = ipa_get_jf_pass_through_formal_id (jfunc); + int idx = ipa_get_jf_pass_through_formal_id (jfunc); if (!(*sum->m_vr)[idx].known_p ()) return; - tree vr_type = ipa_get_type (info, idx); + tree src_type = ipa_get_type (info, idx); value_range srcvr; (*sum->m_vr)[idx].get_vrange (srcvr); - enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); - - if (TREE_CODE_CLASS (operation) == tcc_unary) - { - value_range res (parm_type); - - if (ipa_vr_operation_and_type_effects (res, - srcvr, - operation, parm_type, - vr_type)) - vr.intersect (res); - } - else - { - value_range op_res (vr_type); - value_range res (vr_type); - tree op = ipa_get_jf_pass_through_operand (jfunc); - value_range op_vr (TREE_TYPE (op)); - range_op_handler handler (operation); - - ipa_range_set_and_normalize (op_vr, op); - - if (!handler - || !op_res.supports_type_p (vr_type) - /* Sometimes we try to fold comparison operators using a - pointer type to hold the result instead of a boolean - type. Avoid trapping in the sanity check in - fold_range until this is fixed. */ - || srcvr.undefined_p () - || op_vr.undefined_p () - || !handler.operand_check_p (vr_type, srcvr.type (), op_vr.type ()) - || !handler.fold_range (op_res, vr_type, srcvr, op_vr)) - op_res.set_varying (vr_type); - - if (ipa_vr_operation_and_type_effects (res, - op_res, - NOP_EXPR, parm_type, - vr_type)) - vr.intersect (res); - } + ipa_vr_intersect_with_arith_jfunc (vr, jfunc, srcvr, src_type, parm_type); } } @@ -2523,9 +2533,15 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, || !ipa_vr_supported_type_p (param_type)) return dest_lat->set_to_bottom (); + value_range vr (param_type); + vr.set_varying (param_type); + if (jfunc->m_vr) + ipa_vr_operation_and_type_effects (vr, *jfunc->m_vr, NOP_EXPR, + param_type, + jfunc->m_vr->type ()); + if (jfunc->type == IPA_JF_PASS_THROUGH) { - enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); class ipcp_param_lattices *src_lats @@ -2535,77 +2551,14 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, if (src_lats->m_value_range.bottom_p ()) return dest_lat->set_to_bottom (); - value_range vr (param_type); - if (TREE_CODE_CLASS (operation) == tcc_unary) - ipa_vr_operation_and_type_effects (vr, + if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR + || !ipa_edge_within_scc (cs)) + ipa_vr_intersect_with_arith_jfunc (vr, jfunc, src_lats->m_value_range.m_vr, - operation, param_type, - operand_type); - /* A crude way to prevent unbounded number of value range updates - in SCC components. We should allow limited number of updates within - SCC, too. */ - else if (!ipa_edge_within_scc (cs)) - { - tree op = ipa_get_jf_pass_through_operand (jfunc); - value_range op_vr (TREE_TYPE (op)); - value_range op_res (param_type); - range_op_handler handler (operation); - - ipa_range_set_and_normalize (op_vr, op); - - if (!handler - || !ipa_vr_supported_type_p (operand_type) - /* Sometimes we try to fold comparison operators using a - pointer type to hold the result instead of a boolean - type. Avoid trapping in the sanity check in - fold_range until this is fixed. */ - || src_lats->m_value_range.m_vr.undefined_p () - || op_vr.undefined_p () - || !handler.operand_check_p (operand_type, - src_lats->m_value_range.m_vr.type (), - op_vr.type ()) - || !handler.fold_range (op_res, operand_type, - src_lats->m_value_range.m_vr, op_vr)) - op_res.set_varying (param_type); - - ipa_vr_operation_and_type_effects (vr, - op_res, - NOP_EXPR, param_type, - operand_type); - } - if (!vr.undefined_p () && !vr.varying_p ()) - { - if (jfunc->m_vr) - { - value_range jvr (param_type); - if (ipa_vr_operation_and_type_effects (jvr, *jfunc->m_vr, - NOP_EXPR, - param_type, - jfunc->m_vr->type ())) - vr.intersect (jvr); - } - return dest_lat->meet_with (vr); - } - } - else if (jfunc->type == IPA_JF_CONST) - { - tree val = ipa_get_jf_constant (jfunc); - if (TREE_CODE (val) == INTEGER_CST) - { - val = fold_convert (param_type, val); - if (TREE_OVERFLOW_P (val)) - val = drop_tree_overflow (val); - - value_range tmpvr (val, val); - return dest_lat->meet_with (tmpvr); - } + operand_type, param_type); } - value_range vr (param_type); - if (jfunc->m_vr - && ipa_vr_operation_and_type_effects (vr, *jfunc->m_vr, NOP_EXPR, - param_type, - jfunc->m_vr->type ())) + if (!vr.undefined_p () && !vr.varying_p ()) return dest_lat->meet_with (vr); else return dest_lat->set_to_bottom (); -- 2.47.0