Hi, this patch adds propagation of value ranges through binary operations. This is disabled for value ranges within SCC to avoid infinite loop during propagation. I am bit worried about types here. As far as I can say we have something like
VR in lattice of type1 foo (type1 param) { bar ((type3)((type2)param+(type2)4)) } bar (type4 param) { use param.... } Now in code type1 is called "operand_type" and type4 is called param_type. The arithmetics always happens in operand_type but I do not see why these needs to be necessarily the same? Anyway this immitates what constant jump functions does. Also I noticed that we use NOP_EXPR to convert from type1 all the way to type4 while ipa-fnsummary uses VIEW_CONVERT_EXPR to convert type3 to type4 that seems more valid here. However VR folders always returns varying on VIEW_CONVERT_EXPR (which is probably something that can be fixed) Bootstrapped/regtested x86_64-linux. Does this look OK? Honza * ipa-cp.c (propagate_vr_across_jump_function): Also propagate binary operations. Index: ipa-cp.c =================================================================== --- ipa-cp.c (revision 278094) +++ ipa-cp.c (working copy) @@ -1974,23 +2039,51 @@ propagate_vr_across_jump_function (cgrap if (jfunc->type == IPA_JF_PASS_THROUGH) { enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); + class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); + int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); + class ipcp_param_lattices *src_lats + = ipa_get_parm_lattices (caller_info, src_idx); + tree operand_type = ipa_get_type (caller_info, src_idx); + if (src_lats->m_value_range.bottom_p ()) + return dest_lat->set_to_bottom (); + + value_range vr; if (TREE_CODE_CLASS (operation) == tcc_unary) { - class 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); - class 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 (); - 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); + ipa_vr_operation_and_type_effects (&vr, + &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 (op, op); + value_range op_res,res; + + range_fold_binary_expr (&op_res, operation, operand_type, + &src_lats->m_value_range.m_vr, &op_vr); + 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; + if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr, + NOP_EXPR, + param_type, + jfunc->m_vr->type ())) + vr.intersect (*jfunc->m_vr); + } + return dest_lat->meet_with (&vr); } } else if (jfunc->type == IPA_JF_CONST)