Hi Honza, Here is a re-based version which also addresses the review comments. On 21/07/16 22:54, Jan Hubicka wrote: >> Maybe it is better to separate value range and alignment summary >> writing/reading to different functions. Here is another updated >> version which does this. > > Makes sense to me. Note that the alignment summary propagation can be either > handled by doing bitwise constant propagation and/or extending our value ranges > by stride (as described in > http://www.lighterra.com/papers/valuerangeprop/Patterson1995-ValueRangeProp.pdf > I would like it to go eventually away in favour of more generic solution. > >> -/* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches >> +/* Propagate value range across jump function JFUNC that is associated with >> + edge CS and update DEST_PLATS accordingly. */ >> + >> +static bool >> +propagate_vr_accross_jump_function (cgraph_edge *cs, >> + ipa_jump_func *jfunc, >> + struct ipcp_param_lattices *dest_plats) >> +{ >> + struct ipcp_param_lattices *src_lats; >> + ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range; >> + >> + if (dest_lat->bottom_p ()) >> + return false; >> + >> + 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); >> + >> + if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) >> + return dest_lat->meet_with (src_lats->m_value_range); > > Clearly we can propagate thorugh expressions here (PLUS_EXPR). I have run > into similar issue in loop code that builds simple generic expresisons > (like (int)ssa_name+10) and it would be nice to have easy way to deterine > their value range based on the knowledge of SSA_NAME's valur range. > > Bit this is fine for initial implementaiotn for sure. Indeed. I will do this as a follow up. >> >> +/* Look up all VR information that we have discovered and copy it over >> + to the transformation summary. */ >> + >> +static void >> +ipcp_store_vr_results (void) >> +{ >> + cgraph_node *node; >> + >> + FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) >> + { >> + ipa_node_params *info = IPA_NODE_REF (node); >> + bool found_useful_result = false; >> + >> + if (!opt_for_fn (node->decl, flag_ipa_vrp)) >> + { >> + if (dump_file) >> + fprintf (dump_file, "Not considering %s for VR discovery " >> + "and propagate; -fipa-ipa-vrp: disabled.\n", >> + node->name ()); >> + continue; > > I belive you need to also prevent propagation through functions copmiled with > -fno-ipa-vrp, not only prevent any transformations. Do you mean the following, I was following other implementations. @@ -2264,6 +2430,11 @@ propagate_constants_accross_call (struct cgraph_edge *cs) &dest_plats->bits_lattice); ret |= propagate_aggs_accross_jump_function (cs, jump_func, dest_plats); + if (opt_for_fn (callee->decl, flag_ipa_vrp)) + ret |= propagate_vr_accross_jump_function (cs, + jump_func, dest_plats); + else + ret |= dest_plats->m_value_range.set_to_bottom (); >> +/* Update value range of formal parameters as described in >> + ipcp_transformation_summary. */ >> + >> +static void >> +ipcp_update_vr (struct cgraph_node *node) >> +{ >> + tree fndecl = node->decl; >> + tree parm = DECL_ARGUMENTS (fndecl); >> + tree next_parm = parm; >> + ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); >> + if (!ts || vec_safe_length (ts->m_vr) == 0) >> + return; >> + const vec &vr = *ts->m_vr; >> + unsigned count = vr.length (); >> + >> + for (unsigned i = 0; i < count; ++i, parm = next_parm) >> + { >> + if (node->clone.combined_args_to_skip >> + && bitmap_bit_p (node->clone.combined_args_to_skip, i)) >> + continue; >> + gcc_checking_assert (parm); >> + next_parm = DECL_CHAIN (parm); >> + tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm); >> + >> + if (!ddef || !is_gimple_reg (parm)) >> + continue; >> + >> + if (cgraph_local_p (node) > The test of cgraph_local_p seems redundant here. The analysis phase should not determine > anything if function is reachable non-locally. Removed it. >> +/* Info about value ranges. */ >> + >> +struct GTY(()) ipa_vr >> +{ >> + /* The data fields below are valid only if known is true. */ >> + bool known; >> + enum value_range_type type; >> + tree min; >> + tree max; > What is the point of representing range as trees rather than wide ints. Can they > be non-constant integer? Changed to wide_int after adding that support. LTO Bootstrapped and regression tested on x86_64-linux-gnu with no new regressions, is this OK? Thanks Kugan