aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2024-11-14 20:55:06 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2024-11-14 20:55:22 +0100
commit012f5a22bac26a898ab66655965b07ac23201fdd (patch)
treeb5fe41deaaa78cd760f2fb460b2637201d86e0b3
parent361050589b144913ec05d9d8e10639afa98319a8 (diff)
downloadgcc-012f5a22bac26a898ab66655965b07ac23201fdd.zip
gcc-012f5a22bac26a898ab66655965b07ac23201fdd.tar.gz
gcc-012f5a22bac26a898ab66655965b07ac23201fdd.tar.bz2
ipa: Rationalize IPA-VR computations across pass-through jump functions
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. gcc/ChangeLog: 2024-11-01 Martin Jambor <mjambor@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.
-rw-r--r--gcc/ipa-cp.cc181
1 files changed, 67 insertions, 114 deletions
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index fb65ec0..25741cf 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1692,6 +1692,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. */
@@ -1701,18 +1750,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
@@ -1720,54 +1769,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);
}
}
@@ -2533,9 +2543,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
@@ -2545,77 +2561,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);
- }
+ operand_type, param_type);
}
- 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);
- }
- }
-
- 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 ();