> > well, it all relies on the simple fact that arithmetic jump function > discovery does not cross NOP_EXPRs, or any chain of assignments, so they > are only constructed from things like > > _2 = param_2(D) + 4; > bar (_2); > > but not from > > _1 = (NOP_EXPR) param_2(D); > _2 = _1 + 4; > bar (_2); > > I understand that this is getting ever more fragile and that we may want > to remove this limitation. But there is of course the tradeoff of how > many types we want to stream. But currently there is no type2 or type3.
I see, so type2==type3==type1 and we need only one type conversion which I do. Note that since all types (modulo variadic ones which tends to be horribly broken with LTO) go into global stream streaming an extra type is basically costing you a pointer in memory and one index in stream. Honza > > >> > >> 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. > > Perhaps. > > > 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? > > Yes, it does. > > >> > >> 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; > >> + > > > > Do we really know operation is tcc_binary here? > > it is either NOP_EXPR (which in jump functions is basically a marker > that there really is no operation going on), or something coming from > GIMPLE_UNARY_RHS - which hopefully is tcc_unary and here we can > conveniently share the same path for NOP_EXPR too - or from > GIMPLE_BINARY_RHS, which hopefully is tcc_binary. But an assert may be > reasonable here. > > > > >> + 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); > > Martin