diff options
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r-- | gcc/ipa-cp.c | 97 |
1 files changed, 81 insertions, 16 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 86c6253..8372dfa 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1473,6 +1473,87 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx, return ctx; } +/* 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) +{ + range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type); + if (dst_vr->varying_p () || dst_vr->undefined_p ()) + return false; + return true; +} + +/* Determine value_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. */ + +value_range +ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs, + ipa_jump_func *jfunc, tree parm_type) +{ + value_range vr; + return vr; + if (jfunc->m_vr) + ipa_vr_operation_and_type_effects (&vr, + jfunc->m_vr, + NOP_EXPR, parm_type, + jfunc->m_vr->type ()); + if (vr.singleton_p ()) + return vr; + if (jfunc->type == IPA_JF_PASS_THROUGH) + { + int idx; + ipcp_transformation *sum + = ipcp_get_transformation_summary (cs->caller->inlined_to + ? cs->caller->inlined_to + : cs->caller); + if (!sum || !sum->m_vr) + return vr; + + idx = ipa_get_jf_pass_through_formal_id (jfunc); + + if (!(*sum->m_vr)[idx].known) + return vr; + tree vr_type = ipa_get_type (info, idx); + value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min), + wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max), + (*sum->m_vr)[idx].type); + + enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); + + if (TREE_CODE_CLASS (operation) == tcc_unary) + { + value_range res; + + if (ipa_vr_operation_and_type_effects (&res, + &srcvr, + operation, parm_type, + vr_type)) + vr.intersect (res); + } + else + { + value_range op_res, res; + tree op = ipa_get_jf_pass_through_operand (jfunc); + value_range op_vr (op, op); + + range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr); + if (ipa_vr_operation_and_type_effects (&res, + &op_res, + NOP_EXPR, parm_type, + vr_type)) + vr.intersect (res); + } + } + return vr; +} + /* See if NODE is a clone with a known aggregate value at a given OFFSET of a parameter with the given INDEX. */ @@ -2122,22 +2203,6 @@ 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) -{ - range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type); - if (dst_vr->varying_p () || dst_vr->undefined_p ()) - return false; - return true; -} - /* 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. */ |