aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-prop.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ipa-prop.c')
-rw-r--r--gcc/ipa-prop.c179
1 files changed, 173 insertions, 6 deletions
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index b86a4a0..feecd23 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -311,6 +311,19 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
}
else
fprintf (f, " Unknown bits\n");
+
+ if (jump_func->vr_known)
+ {
+ fprintf (f, " VR ");
+ fprintf (f, "%s[",
+ (jump_func->m_vr.type == VR_ANTI_RANGE) ? "~" : "");
+ print_decs (jump_func->m_vr.min, f);
+ fprintf (f, ", ");
+ print_decs (jump_func->m_vr.max, f);
+ fprintf (f, "]\n");
+ }
+ else
+ fprintf (f, " Unknown VR\n");
}
}
@@ -391,6 +404,7 @@ ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
jfunc->type = IPA_JF_UNKNOWN;
jfunc->alignment.known = false;
jfunc->bits.known = false;
+ jfunc->vr_known = false;
}
/* Set JFUNC to be a copy of another jmp (to be used by jump function
@@ -1680,9 +1694,27 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
}
else
gcc_assert (!jfunc->alignment.known);
+ gcc_assert (!jfunc->vr_known);
}
else
- gcc_assert (!jfunc->alignment.known);
+ {
+ wide_int min, max;
+ value_range_type type;
+ if (TREE_CODE (arg) == SSA_NAME
+ && param_type
+ && (type = get_range_info (arg, &min, &max))
+ && (type == VR_RANGE || type == VR_ANTI_RANGE)
+ && (min.get_precision () <= TYPE_PRECISION (param_type)))
+ {
+ jfunc->vr_known = true;
+ jfunc->m_vr.type = type;
+ jfunc->m_vr.min = wide_int_to_tree (param_type, min);
+ jfunc->m_vr.max = wide_int_to_tree (param_type, max);
+ }
+ else
+ gcc_assert (!jfunc->vr_known);
+ gcc_assert (!jfunc->alignment.known);
+ }
if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
&& (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
@@ -3709,16 +3741,28 @@ ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
ipcp_transformation_summary *src_trans = ipcp_get_transformation_summary (src);
- if (src_trans && vec_safe_length (src_trans->alignments) > 0)
+ if (src_trans)
{
ipcp_grow_transformations_if_necessary ();
src_trans = ipcp_get_transformation_summary (src);
const vec<ipa_alignment, va_gc> *src_alignments = src_trans->alignments;
+ const vec<ipa_vr, va_gc> *src_vr = src_trans->m_vr;
vec<ipa_alignment, va_gc> *&dst_alignments
= ipcp_get_transformation_summary (dst)->alignments;
- vec_safe_reserve_exact (dst_alignments, src_alignments->length ());
- for (unsigned i = 0; i < src_alignments->length (); ++i)
- dst_alignments->quick_push ((*src_alignments)[i]);
+ vec<ipa_vr, va_gc> *&dst_vr
+ = ipcp_get_transformation_summary (dst)->m_vr;
+ if (vec_safe_length (src_trans->alignments) > 0)
+ {
+ vec_safe_reserve_exact (dst_alignments, src_alignments->length ());
+ for (unsigned i = 0; i < src_alignments->length (); ++i)
+ dst_alignments->quick_push ((*src_alignments)[i]);
+ }
+ if (vec_safe_length (src_trans->m_vr) > 0)
+ {
+ vec_safe_reserve_exact (dst_vr, src_vr->length ());
+ for (unsigned i = 0; i < src_vr->length (); ++i)
+ dst_vr->quick_push ((*src_vr)[i]);
+ }
}
if (src_trans && vec_safe_length (src_trans->bits) > 0)
@@ -4660,6 +4704,15 @@ ipa_write_jump_function (struct output_block *ob,
streamer_write_widest_int (ob, jump_func->bits.value);
streamer_write_widest_int (ob, jump_func->bits.mask);
}
+ bp_pack_value (&bp, jump_func->vr_known, 1);
+ streamer_write_bitpack (&bp);
+ if (jump_func->vr_known)
+ {
+ streamer_write_enum (ob->main_stream, value_rang_type,
+ VR_LAST, jump_func->m_vr.type);
+ stream_write_tree (ob, jump_func->m_vr.min, true);
+ stream_write_tree (ob, jump_func->m_vr.max, true);
+ }
}
/* Read in jump function JUMP_FUNC from IB. */
@@ -4747,6 +4800,20 @@ ipa_read_jump_function (struct lto_input_block *ib,
}
else
jump_func->bits.known = false;
+
+ struct bitpack_d vr_bp = streamer_read_bitpack (ib);
+ bool vr_known = bp_unpack_value (&vr_bp, 1);
+ if (vr_known)
+ {
+ jump_func->vr_known = true;
+ jump_func->m_vr.type = streamer_read_enum (ib,
+ value_range_type,
+ VR_LAST);
+ jump_func->m_vr.min = stream_read_tree (ib, data_in);
+ jump_func->m_vr.max = stream_read_tree (ib, data_in);
+ }
+ else
+ jump_func->vr_known = false;
}
/* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
@@ -5113,7 +5180,29 @@ write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
else
streamer_write_uhwi (ob, 0);
- ts = ipcp_get_transformation_summary (node);
+ if (ts && vec_safe_length (ts->m_vr) > 0)
+ {
+ count = ts->m_vr->length ();
+ streamer_write_uhwi (ob, count);
+ for (unsigned i = 0; i < count; ++i)
+ {
+ struct bitpack_d bp;
+ ipa_vr *parm_vr = &(*ts->m_vr)[i];
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, parm_vr->known, 1);
+ streamer_write_bitpack (&bp);
+ if (parm_vr->known)
+ {
+ streamer_write_enum (ob->main_stream, value_rang_type,
+ VR_LAST, parm_vr->type);
+ streamer_write_wide_int (ob, parm_vr->min);
+ streamer_write_wide_int (ob, parm_vr->max);
+ }
+ }
+ }
+ else
+ streamer_write_uhwi (ob, 0);
+
if (ts && vec_safe_length (ts->bits) > 0)
{
count = ts->bits->length ();
@@ -5191,6 +5280,30 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
if (count > 0)
{
ipcp_grow_transformations_if_necessary ();
+
+ ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
+ vec_safe_grow_cleared (ts->m_vr, count);
+ for (i = 0; i < count; i++)
+ {
+ ipa_vr *parm_vr;
+ parm_vr = &(*ts->m_vr)[i];
+ struct bitpack_d bp;
+ bp = streamer_read_bitpack (ib);
+ parm_vr->known = bp_unpack_value (&bp, 1);
+ if (parm_vr->known)
+ {
+ parm_vr->type = streamer_read_enum (ib, value_range_type,
+ VR_LAST);
+ parm_vr->min = streamer_read_wide_int (ib);
+ parm_vr->max = streamer_read_wide_int (ib);
+ }
+ }
+ }
+ count = streamer_read_uhwi (ib);
+ if (count > 0)
+ {
+ ipcp_grow_transformations_if_necessary ();
+
ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
vec_safe_grow_cleared (ts->bits, count);
@@ -5558,6 +5671,59 @@ ipcp_update_bits (struct cgraph_node *node)
}
}
+/* 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<ipa_vr, va_gc> &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 (vr[i].known
+ && INTEGRAL_TYPE_P (TREE_TYPE (ddef))
+ && !POINTER_TYPE_P (TREE_TYPE (ddef))
+ && (vr[i].type == VR_RANGE || vr[i].type == VR_ANTI_RANGE))
+ {
+ tree type = TREE_TYPE (ddef);
+ unsigned prec = TYPE_PRECISION (type);
+ if (dump_file)
+ {
+ fprintf (dump_file, "Setting value range of param %u ", i);
+ fprintf (dump_file, "%s[",
+ (vr[i].type == VR_ANTI_RANGE) ? "~" : "");
+ print_decs (vr[i].min, dump_file);
+ fprintf (dump_file, ", ");
+ print_decs (vr[i].max, dump_file);
+ fprintf (dump_file, "]\n");
+ }
+ set_range_info (ddef, vr[i].type,
+ wide_int_storage::from (vr[i].min, prec,
+ TYPE_SIGN (type)),
+ wide_int_storage::from (vr[i].max, prec,
+ TYPE_SIGN (type)));
+ }
+ }
+}
+
/* IPCP transformation phase doing propagation of aggregate values. */
unsigned int
@@ -5578,6 +5744,7 @@ ipcp_transform_function (struct cgraph_node *node)
ipcp_update_alignments (node);
ipcp_update_bits (node);
+ ipcp_update_vr (node);
aggval = ipa_get_agg_replacements_for_node (node);
if (!aggval)
return 0;