[PR 78140] Reuse same IPA bits and VR info
2017-03-01 Martin Jambor <mjambor@suse.cz> PR lto/78140 * ipa-prop.h (ipa_bits): Removed field known. (ipa_jump_func): Removed field vr_known. Changed fields bits and m_vr to pointers. Adjusted their comments to warn about their sharing. (ipcp_transformation_summary): Change bits to a vector of pointers. (ipa_check_create_edge_args): Moved to ipa-prop.c, declare. (ipa_get_ipa_bits_for_value): Declare. * tree-vrp.h (value_range): Mark as GTY((for_user)). * ipa-prop.c (ipa_bit_ggc_hash_traits): New. (ipa_bits_hash_table): Likewise. (ipa_vr_ggc_hash_traits): Likewise. (ipa_vr_hash_table): Likewise. (ipa_print_node_jump_functions_for_edge): Adjust for bits and m_vr being pointers and vr_known being removed. (ipa_set_jf_unknown): Likewise. (ipa_get_ipa_bits_for_value): New function. (ipa_set_jfunc_bits): Likewise. (ipa_get_value_range): New overloaded functions. (ipa_set_jfunc_vr): Likewise. (ipa_compute_jump_functions_for_edge): Use the above functions to construct bits and vr parts of jump functions. (ipa_check_create_edge_args): Move here from ipa-prop.h, also allocate ipa_bits_hash_table and ipa_vr_hash_table if they do not already exist. (ipcp_grow_transformations_if_necessary): Also allocate ipa_bits_hash_table and ipa_vr_hash_table if they do not already exist. (ipa_node_params_t::duplicate): Do not copy bits, just pointers to them. Fix too long lines. (ipa_write_jump_function): Adjust for bits and m_vr being pointers and vr_known being removed. (ipa_read_jump_function): Use new setter functions to construct bits and vr parts of jump functions or set them to NULL. (write_ipcp_transformation_info): Adjust for bits being pointers. (read_ipcp_transformation_info): Likewise. (ipcp_update_bits): Likewise. Fix excessively long lines a trailing space. Include gt-ipa-prop.h. * ipa-cp.c (propagate_bits_across_jump_function): Adjust for bits being pointers. (ipcp_store_bits_results): Likewise. (propagate_vr_across_jump_function): Adjust for m_vr being a pointer. Do not write to existing jump functions but use a temporary instead. From-SVN: r245805
This commit is contained in:
parent
42132674e5
commit
86cd0334f3
|
@ -1,3 +1,49 @@
|
||||||
|
2017-03-01 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
PR lto/78140
|
||||||
|
* ipa-prop.h (ipa_bits): Removed field known.
|
||||||
|
(ipa_jump_func): Removed field vr_known. Changed fields bits and m_vr
|
||||||
|
to pointers. Adjusted their comments to warn about their sharing.
|
||||||
|
(ipcp_transformation_summary): Change bits to a vector of pointers.
|
||||||
|
(ipa_check_create_edge_args): Moved to ipa-prop.c, declare.
|
||||||
|
(ipa_get_ipa_bits_for_value): Declare.
|
||||||
|
* tree-vrp.h (value_range): Mark as GTY((for_user)).
|
||||||
|
* ipa-prop.c (ipa_bit_ggc_hash_traits): New.
|
||||||
|
(ipa_bits_hash_table): Likewise.
|
||||||
|
(ipa_vr_ggc_hash_traits): Likewise.
|
||||||
|
(ipa_vr_hash_table): Likewise.
|
||||||
|
(ipa_print_node_jump_functions_for_edge): Adjust for bits and m_vr
|
||||||
|
being pointers and vr_known being removed.
|
||||||
|
(ipa_set_jf_unknown): Likewise.
|
||||||
|
(ipa_get_ipa_bits_for_value): New function.
|
||||||
|
(ipa_set_jfunc_bits): Likewise.
|
||||||
|
(ipa_get_value_range): New overloaded functions.
|
||||||
|
(ipa_set_jfunc_vr): Likewise.
|
||||||
|
(ipa_compute_jump_functions_for_edge): Use the above functions to
|
||||||
|
construct bits and vr parts of jump functions.
|
||||||
|
(ipa_check_create_edge_args): Move here from ipa-prop.h, also allocate
|
||||||
|
ipa_bits_hash_table and ipa_vr_hash_table if they do not already
|
||||||
|
exist.
|
||||||
|
(ipcp_grow_transformations_if_necessary): Also allocate
|
||||||
|
ipa_bits_hash_table and ipa_vr_hash_table if they do not already
|
||||||
|
exist.
|
||||||
|
(ipa_node_params_t::duplicate): Do not copy bits, just pointers to
|
||||||
|
them. Fix too long lines.
|
||||||
|
(ipa_write_jump_function): Adjust for bits and m_vr being pointers and
|
||||||
|
vr_known being removed.
|
||||||
|
(ipa_read_jump_function): Use new setter functions to construct bits
|
||||||
|
and vr parts of jump functions or set them to NULL.
|
||||||
|
(write_ipcp_transformation_info): Adjust for bits being pointers.
|
||||||
|
(read_ipcp_transformation_info): Likewise.
|
||||||
|
(ipcp_update_bits): Likewise. Fix excessively long lines a trailing
|
||||||
|
space.
|
||||||
|
Include gt-ipa-prop.h.
|
||||||
|
* ipa-cp.c (propagate_bits_across_jump_function): Adjust for bits
|
||||||
|
being pointers.
|
||||||
|
(ipcp_store_bits_results): Likewise.
|
||||||
|
(propagate_vr_across_jump_function): Adjust for m_vr being a pointer.
|
||||||
|
Do not write to existing jump functions but use a temporary instead.
|
||||||
|
|
||||||
2017-03-01 Jakub Jelinek <jakub@redhat.com>
|
2017-03-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c++/79681
|
PR c++/79681
|
||||||
|
|
49
gcc/ipa-cp.c
49
gcc/ipa-cp.c
|
@ -1819,8 +1819,8 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
|
||||||
and we store it in jump function during analysis stage. */
|
and we store it in jump function during analysis stage. */
|
||||||
|
|
||||||
if (src_lats->bits_lattice.bottom_p ()
|
if (src_lats->bits_lattice.bottom_p ()
|
||||||
&& jfunc->bits.known)
|
&& jfunc->bits)
|
||||||
return dest_lattice->meet_with (jfunc->bits.value, jfunc->bits.mask,
|
return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
|
||||||
precision);
|
precision);
|
||||||
else
|
else
|
||||||
return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn,
|
return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn,
|
||||||
|
@ -1829,10 +1829,9 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
|
||||||
|
|
||||||
else if (jfunc->type == IPA_JF_ANCESTOR)
|
else if (jfunc->type == IPA_JF_ANCESTOR)
|
||||||
return dest_lattice->set_to_bottom ();
|
return dest_lattice->set_to_bottom ();
|
||||||
|
else if (jfunc->bits)
|
||||||
else if (jfunc->bits.known)
|
return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
|
||||||
return dest_lattice->meet_with (jfunc->bits.value, jfunc->bits.mask, precision);
|
precision);
|
||||||
|
|
||||||
else
|
else
|
||||||
return dest_lattice->set_to_bottom ();
|
return dest_lattice->set_to_bottom ();
|
||||||
}
|
}
|
||||||
|
@ -1903,19 +1902,21 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
|
||||||
val = fold_convert (param_type, val);
|
val = fold_convert (param_type, val);
|
||||||
if (TREE_OVERFLOW_P (val))
|
if (TREE_OVERFLOW_P (val))
|
||||||
val = drop_tree_overflow (val);
|
val = drop_tree_overflow (val);
|
||||||
jfunc->vr_known = true;
|
|
||||||
jfunc->m_vr.type = VR_RANGE;
|
value_range tmpvr;
|
||||||
jfunc->m_vr.min = val;
|
memset (&tmpvr, 0, sizeof (tmpvr));
|
||||||
jfunc->m_vr.max = val;
|
tmpvr.type = VR_RANGE;
|
||||||
return dest_lat->meet_with (&jfunc->m_vr);
|
tmpvr.min = val;
|
||||||
|
tmpvr.max = val;
|
||||||
|
return dest_lat->meet_with (&tmpvr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value_range vr;
|
value_range vr;
|
||||||
if (jfunc->vr_known
|
if (jfunc->m_vr
|
||||||
&& ipa_vr_operation_and_type_effects (&vr, &jfunc->m_vr, NOP_EXPR,
|
&& ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
|
||||||
param_type,
|
param_type,
|
||||||
TREE_TYPE (jfunc->m_vr.min)))
|
TREE_TYPE (jfunc->m_vr->min)))
|
||||||
return dest_lat->meet_with (&vr);
|
return dest_lat->meet_with (&vr);
|
||||||
else
|
else
|
||||||
return dest_lat->set_to_bottom ();
|
return dest_lat->set_to_bottom ();
|
||||||
|
@ -4870,19 +4871,17 @@ ipcp_store_bits_results (void)
|
||||||
for (unsigned i = 0; i < count; i++)
|
for (unsigned i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
|
ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
|
||||||
ipa_bits bits_jfunc;
|
ipa_bits *jfbits;
|
||||||
|
|
||||||
if (plats->bits_lattice.constant_p ())
|
if (plats->bits_lattice.constant_p ())
|
||||||
{
|
jfbits
|
||||||
bits_jfunc.known = true;
|
= ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (),
|
||||||
bits_jfunc.value = plats->bits_lattice.get_value ();
|
plats->bits_lattice.get_mask ());
|
||||||
bits_jfunc.mask = plats->bits_lattice.get_mask ();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
bits_jfunc.known = false;
|
jfbits = NULL;
|
||||||
|
|
||||||
ts->bits->quick_push (bits_jfunc);
|
ts->bits->quick_push (jfbits);
|
||||||
if (!dump_file || !bits_jfunc.known)
|
if (!dump_file || !jfbits)
|
||||||
continue;
|
continue;
|
||||||
if (!dumped_sth)
|
if (!dumped_sth)
|
||||||
{
|
{
|
||||||
|
@ -4891,9 +4890,9 @@ ipcp_store_bits_results (void)
|
||||||
dumped_sth = true;
|
dumped_sth = true;
|
||||||
}
|
}
|
||||||
fprintf (dump_file, " param %i: value = ", i);
|
fprintf (dump_file, " param %i: value = ", i);
|
||||||
print_hex (bits_jfunc.value, dump_file);
|
print_hex (jfbits->value, dump_file);
|
||||||
fprintf (dump_file, ", mask = ");
|
fprintf (dump_file, ", mask = ");
|
||||||
print_hex (bits_jfunc.mask, dump_file);
|
print_hex (jfbits->mask, dump_file);
|
||||||
fprintf (dump_file, "\n");
|
fprintf (dump_file, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
371
gcc/ipa-prop.c
371
gcc/ipa-prop.c
|
@ -60,6 +60,93 @@ vec<ipcp_transformation_summary, va_gc> *ipcp_transformations;
|
||||||
/* Vector where the parameter infos are actually stored. */
|
/* Vector where the parameter infos are actually stored. */
|
||||||
vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
|
vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
|
||||||
|
|
||||||
|
/* Traits for a hash table for reusing already existing ipa_bits. */
|
||||||
|
|
||||||
|
struct ipa_bit_ggc_hash_traits : public ggc_cache_remove <ipa_bits *>
|
||||||
|
{
|
||||||
|
typedef ipa_bits *value_type;
|
||||||
|
typedef ipa_bits *compare_type;
|
||||||
|
static hashval_t
|
||||||
|
hash (const ipa_bits *p)
|
||||||
|
{
|
||||||
|
hashval_t t = (hashval_t) p->value.to_shwi ();
|
||||||
|
return iterative_hash_host_wide_int (p->mask.to_shwi (), t);
|
||||||
|
}
|
||||||
|
static bool
|
||||||
|
equal (const ipa_bits *a, const ipa_bits *b)
|
||||||
|
{
|
||||||
|
return a->value == b->value && a->mask == b->mask;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
mark_empty (ipa_bits *&p)
|
||||||
|
{
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
static bool
|
||||||
|
is_empty (const ipa_bits *p)
|
||||||
|
{
|
||||||
|
return p == NULL;
|
||||||
|
}
|
||||||
|
static bool
|
||||||
|
is_deleted (const ipa_bits *p)
|
||||||
|
{
|
||||||
|
return p == reinterpret_cast<const ipa_bits *> (1);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
mark_deleted (ipa_bits *&p)
|
||||||
|
{
|
||||||
|
p = reinterpret_cast<ipa_bits *> (1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Hash table for avoid repeated allocations of equal ipa_bits. */
|
||||||
|
static GTY ((cache)) hash_table<ipa_bit_ggc_hash_traits> *ipa_bits_hash_table;
|
||||||
|
|
||||||
|
/* Traits for a hash table for reusing value_ranges used for IPA. Note that
|
||||||
|
the equiv bitmap is not hashed and is expected to be NULL. */
|
||||||
|
|
||||||
|
struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
|
||||||
|
{
|
||||||
|
typedef value_range *value_type;
|
||||||
|
typedef value_range *compare_type;
|
||||||
|
static hashval_t
|
||||||
|
hash (const value_range *p)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (!p->equiv);
|
||||||
|
hashval_t t = (hashval_t) p->type;
|
||||||
|
t = iterative_hash_expr (p->min, t);
|
||||||
|
return iterative_hash_expr (p->max, t);
|
||||||
|
}
|
||||||
|
static bool
|
||||||
|
equal (const value_range *a, const value_range *b)
|
||||||
|
{
|
||||||
|
return a->type == b->type && a->min == b->min && a->max == b->max;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
mark_empty (value_range *&p)
|
||||||
|
{
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
static bool
|
||||||
|
is_empty (const value_range *p)
|
||||||
|
{
|
||||||
|
return p == NULL;
|
||||||
|
}
|
||||||
|
static bool
|
||||||
|
is_deleted (const value_range *p)
|
||||||
|
{
|
||||||
|
return p == reinterpret_cast<const value_range *> (1);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
mark_deleted (value_range *&p)
|
||||||
|
{
|
||||||
|
p = reinterpret_cast<value_range *> (1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Hash table for avoid repeated allocations of equal value_ranges. */
|
||||||
|
static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
|
||||||
|
|
||||||
/* Holders of ipa cgraph hooks: */
|
/* Holders of ipa cgraph hooks: */
|
||||||
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
|
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
|
||||||
static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
|
static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
|
||||||
|
@ -298,23 +385,25 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
|
||||||
ctx->dump (dump_file);
|
ctx->dump (dump_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jump_func->bits.known)
|
if (jump_func->bits)
|
||||||
{
|
{
|
||||||
fprintf (f, " value: "); print_hex (jump_func->bits.value, f);
|
fprintf (f, " value: ");
|
||||||
fprintf (f, ", mask: "); print_hex (jump_func->bits.mask, f);
|
print_hex (jump_func->bits->value, f);
|
||||||
|
fprintf (f, ", mask: ");
|
||||||
|
print_hex (jump_func->bits->mask, f);
|
||||||
fprintf (f, "\n");
|
fprintf (f, "\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fprintf (f, " Unknown bits\n");
|
fprintf (f, " Unknown bits\n");
|
||||||
|
|
||||||
if (jump_func->vr_known)
|
if (jump_func->m_vr)
|
||||||
{
|
{
|
||||||
fprintf (f, " VR ");
|
fprintf (f, " VR ");
|
||||||
fprintf (f, "%s[",
|
fprintf (f, "%s[",
|
||||||
(jump_func->m_vr.type == VR_ANTI_RANGE) ? "~" : "");
|
(jump_func->m_vr->type == VR_ANTI_RANGE) ? "~" : "");
|
||||||
print_decs (jump_func->m_vr.min, f);
|
print_decs (jump_func->m_vr->min, f);
|
||||||
fprintf (f, ", ");
|
fprintf (f, ", ");
|
||||||
print_decs (jump_func->m_vr.max, f);
|
print_decs (jump_func->m_vr->max, f);
|
||||||
fprintf (f, "]\n");
|
fprintf (f, "]\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -397,8 +486,8 @@ static void
|
||||||
ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
|
ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
|
||||||
{
|
{
|
||||||
jfunc->type = IPA_JF_UNKNOWN;
|
jfunc->type = IPA_JF_UNKNOWN;
|
||||||
jfunc->bits.known = false;
|
jfunc->bits = NULL;
|
||||||
jfunc->vr_known = false;
|
jfunc->m_vr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set JFUNC to be a copy of another jmp (to be used by jump function
|
/* Set JFUNC to be a copy of another jmp (to be used by jump function
|
||||||
|
@ -1658,6 +1747,91 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return ipa_bits with VALUE and MASK values, which can be either a newly
|
||||||
|
allocated structure or a previously existing one shared with other jump
|
||||||
|
functions and/or transformation summaries. */
|
||||||
|
|
||||||
|
ipa_bits *
|
||||||
|
ipa_get_ipa_bits_for_value (const widest_int &value, const widest_int &mask)
|
||||||
|
{
|
||||||
|
ipa_bits tmp;
|
||||||
|
tmp.value = value;
|
||||||
|
tmp.mask = mask;
|
||||||
|
|
||||||
|
ipa_bits **slot = ipa_bits_hash_table->find_slot (&tmp, INSERT);
|
||||||
|
if (*slot)
|
||||||
|
return *slot;
|
||||||
|
|
||||||
|
ipa_bits *res = ggc_alloc<ipa_bits> ();
|
||||||
|
res->value = value;
|
||||||
|
res->mask = mask;
|
||||||
|
*slot = res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign to JF a pointer to ipa_bits structure with VALUE and MASK. Use hash
|
||||||
|
table in order to avoid creating multiple same ipa_bits structures. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ipa_set_jfunc_bits (ipa_jump_func *jf, const widest_int &value,
|
||||||
|
const widest_int &mask)
|
||||||
|
{
|
||||||
|
jf->bits = ipa_get_ipa_bits_for_value (value, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a pointer to a value_range just like *TMP, but either find it in
|
||||||
|
ipa_vr_hash_table or allocate it in GC memory. TMP->equiv must be NULL. */
|
||||||
|
|
||||||
|
static value_range *
|
||||||
|
ipa_get_value_range (value_range *tmp)
|
||||||
|
{
|
||||||
|
value_range **slot = ipa_vr_hash_table->find_slot (tmp, INSERT);
|
||||||
|
if (*slot)
|
||||||
|
return *slot;
|
||||||
|
|
||||||
|
value_range *vr = ggc_alloc<value_range> ();
|
||||||
|
*vr = *tmp;
|
||||||
|
*slot = vr;
|
||||||
|
|
||||||
|
return vr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a pointer to a value range consisting of TYPE, MIN, MAX and an empty
|
||||||
|
equiv set. Use hash table in order to avoid creating multiple same copies of
|
||||||
|
value_ranges. */
|
||||||
|
|
||||||
|
static value_range *
|
||||||
|
ipa_get_value_range (enum value_range_type type, tree min, tree max)
|
||||||
|
{
|
||||||
|
value_range tmp;
|
||||||
|
tmp.type = type;
|
||||||
|
tmp.min = min;
|
||||||
|
tmp.max = max;
|
||||||
|
tmp.equiv = NULL;
|
||||||
|
return ipa_get_value_range (&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign to JF a pointer to a value_range structure with TYPE, MIN and MAX and
|
||||||
|
a NULL equiv bitmap. Use hash table in order to avoid creating multiple
|
||||||
|
same value_range structures. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ipa_set_jfunc_vr (ipa_jump_func *jf, enum value_range_type type,
|
||||||
|
tree min, tree max)
|
||||||
|
{
|
||||||
|
jf->m_vr = ipa_get_value_range (type, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign to JF a pointer to a value_range just liek TMP but either fetch a
|
||||||
|
copy from ipa_vr_hash_table or allocate a new on in GC memory. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ipa_set_jfunc_vr (ipa_jump_func *jf, value_range *tmp)
|
||||||
|
{
|
||||||
|
jf->m_vr = ipa_get_value_range (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute jump function for all arguments of callsite CS and insert the
|
/* Compute jump function for all arguments of callsite CS and insert the
|
||||||
information in the jump_functions array in the ipa_edge_args corresponding
|
information in the jump_functions array in the ipa_edge_args corresponding
|
||||||
to this callsite. */
|
to this callsite. */
|
||||||
|
@ -1714,14 +1888,11 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
|
||||||
|
|
||||||
if (addr_nonzero)
|
if (addr_nonzero)
|
||||||
{
|
{
|
||||||
jfunc->vr_known = true;
|
tree z = build_int_cst (TREE_TYPE (arg), 0);
|
||||||
jfunc->m_vr.type = VR_ANTI_RANGE;
|
ipa_set_jfunc_vr (jfunc, VR_ANTI_RANGE, z, z);
|
||||||
jfunc->m_vr.min = build_int_cst (TREE_TYPE (arg), 0);
|
|
||||||
jfunc->m_vr.max = build_int_cst (TREE_TYPE (arg), 0);
|
|
||||||
jfunc->m_vr.equiv = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gcc_assert (!jfunc->vr_known);
|
gcc_assert (!jfunc->m_vr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1732,56 +1903,48 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
|
||||||
&& (type = get_range_info (arg, &min, &max))
|
&& (type = get_range_info (arg, &min, &max))
|
||||||
&& (type == VR_RANGE || type == VR_ANTI_RANGE))
|
&& (type == VR_RANGE || type == VR_ANTI_RANGE))
|
||||||
{
|
{
|
||||||
value_range vr;
|
value_range tmpvr,resvr;
|
||||||
|
|
||||||
vr.type = type;
|
tmpvr.type = type;
|
||||||
vr.min = wide_int_to_tree (TREE_TYPE (arg), min);
|
tmpvr.min = wide_int_to_tree (TREE_TYPE (arg), min);
|
||||||
vr.max = wide_int_to_tree (TREE_TYPE (arg), max);
|
tmpvr.max = wide_int_to_tree (TREE_TYPE (arg), max);
|
||||||
vr.equiv = NULL;
|
tmpvr.equiv = NULL;
|
||||||
extract_range_from_unary_expr (&jfunc->m_vr,
|
memset (&resvr, 0, sizeof (resvr));
|
||||||
NOP_EXPR,
|
extract_range_from_unary_expr (&resvr, NOP_EXPR, param_type,
|
||||||
param_type,
|
&tmpvr, TREE_TYPE (arg));
|
||||||
&vr, TREE_TYPE (arg));
|
if (resvr.type == VR_RANGE || resvr.type == VR_ANTI_RANGE)
|
||||||
if (jfunc->m_vr.type == VR_RANGE
|
ipa_set_jfunc_vr (jfunc, &resvr);
|
||||||
|| jfunc->m_vr.type == VR_ANTI_RANGE)
|
|
||||||
jfunc->vr_known = true;
|
|
||||||
else
|
else
|
||||||
jfunc->vr_known = false;
|
gcc_assert (!jfunc->m_vr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gcc_assert (!jfunc->vr_known);
|
gcc_assert (!jfunc->m_vr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
|
if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
|
||||||
&& (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
|
&& (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
|
||||||
{
|
{
|
||||||
jfunc->bits.known = true;
|
|
||||||
|
|
||||||
if (TREE_CODE (arg) == SSA_NAME)
|
if (TREE_CODE (arg) == SSA_NAME)
|
||||||
{
|
ipa_set_jfunc_bits (jfunc, 0,
|
||||||
jfunc->bits.value = 0;
|
widest_int::from (get_nonzero_bits (arg),
|
||||||
jfunc->bits.mask = widest_int::from (get_nonzero_bits (arg),
|
TYPE_SIGN (TREE_TYPE (arg))));
|
||||||
TYPE_SIGN (TREE_TYPE (arg)));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
|
||||||
jfunc->bits.value = wi::to_widest (arg);
|
|
||||||
jfunc->bits.mask = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (POINTER_TYPE_P (TREE_TYPE (arg)))
|
else if (POINTER_TYPE_P (TREE_TYPE (arg)))
|
||||||
{
|
{
|
||||||
unsigned HOST_WIDE_INT bitpos;
|
unsigned HOST_WIDE_INT bitpos;
|
||||||
unsigned align;
|
unsigned align;
|
||||||
|
|
||||||
jfunc->bits.known = true;
|
|
||||||
get_pointer_alignment_1 (arg, &align, &bitpos);
|
get_pointer_alignment_1 (arg, &align, &bitpos);
|
||||||
jfunc->bits.mask = wi::mask<widest_int>(TYPE_PRECISION (TREE_TYPE (arg)), false)
|
widest_int mask
|
||||||
|
= wi::mask<widest_int>(TYPE_PRECISION (TREE_TYPE (arg)), false)
|
||||||
.and_not (align / BITS_PER_UNIT - 1);
|
.and_not (align / BITS_PER_UNIT - 1);
|
||||||
jfunc->bits.value = bitpos / BITS_PER_UNIT;
|
widest_int value = bitpos / BITS_PER_UNIT;
|
||||||
|
ipa_set_jfunc_bits (jfunc, value, mask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gcc_assert (!jfunc->bits.known);
|
gcc_assert (!jfunc->bits);
|
||||||
|
|
||||||
if (is_gimple_ip_invariant (arg)
|
if (is_gimple_ip_invariant (arg)
|
||||||
|| (VAR_P (arg)
|
|| (VAR_P (arg)
|
||||||
|
@ -3545,6 +3708,22 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure that array of edge arguments infos is big enough to accommodate a
|
||||||
|
structure for all edges and reallocates it if not. Also, allocate
|
||||||
|
associated hash tables is they do not already exist. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ipa_check_create_edge_args (void)
|
||||||
|
{
|
||||||
|
if (vec_safe_length (ipa_edge_args_vector)
|
||||||
|
<= (unsigned) symtab->edges_max_uid)
|
||||||
|
vec_safe_grow_cleared (ipa_edge_args_vector, symtab->edges_max_uid + 1);
|
||||||
|
if (!ipa_bits_hash_table)
|
||||||
|
ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
|
||||||
|
if (!ipa_vr_hash_table)
|
||||||
|
ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
|
||||||
|
}
|
||||||
|
|
||||||
/* Frees all dynamically allocated structures that the argument info points
|
/* Frees all dynamically allocated structures that the argument info points
|
||||||
to. */
|
to. */
|
||||||
|
|
||||||
|
@ -3581,7 +3760,8 @@ ipa_free_all_node_params (void)
|
||||||
ipa_node_params_sum = NULL;
|
ipa_node_params_sum = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grow ipcp_transformations if necessary. */
|
/* Grow ipcp_transformations if necessary. Also allocate any necessary hash
|
||||||
|
tables if they do not already exist. */
|
||||||
|
|
||||||
void
|
void
|
||||||
ipcp_grow_transformations_if_necessary (void)
|
ipcp_grow_transformations_if_necessary (void)
|
||||||
|
@ -3589,6 +3769,10 @@ ipcp_grow_transformations_if_necessary (void)
|
||||||
if (vec_safe_length (ipcp_transformations)
|
if (vec_safe_length (ipcp_transformations)
|
||||||
<= (unsigned) symtab->cgraph_max_uid)
|
<= (unsigned) symtab->cgraph_max_uid)
|
||||||
vec_safe_grow_cleared (ipcp_transformations, symtab->cgraph_max_uid + 1);
|
vec_safe_grow_cleared (ipcp_transformations, symtab->cgraph_max_uid + 1);
|
||||||
|
if (!ipa_bits_hash_table)
|
||||||
|
ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
|
||||||
|
if (!ipa_vr_hash_table)
|
||||||
|
ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the aggregate replacements of NODE to be AGGVALS. */
|
/* Set the aggregate replacements of NODE to be AGGVALS. */
|
||||||
|
@ -3775,12 +3959,18 @@ ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
|
||||||
ipa_set_node_agg_value_chain (dst, new_av);
|
ipa_set_node_agg_value_chain (dst, new_av);
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcp_transformation_summary *src_trans = ipcp_get_transformation_summary (src);
|
ipcp_transformation_summary *src_trans
|
||||||
|
= ipcp_get_transformation_summary (src);
|
||||||
|
|
||||||
if (src_trans)
|
if (src_trans)
|
||||||
{
|
{
|
||||||
ipcp_grow_transformations_if_necessary ();
|
ipcp_grow_transformations_if_necessary ();
|
||||||
src_trans = ipcp_get_transformation_summary (src);
|
src_trans = ipcp_get_transformation_summary (src);
|
||||||
|
ipcp_transformation_summary *dst_trans
|
||||||
|
= ipcp_get_transformation_summary (dst);
|
||||||
|
|
||||||
|
dst_trans->bits = vec_safe_copy (src_trans->bits);
|
||||||
|
|
||||||
const vec<ipa_vr, va_gc> *src_vr = src_trans->m_vr;
|
const vec<ipa_vr, va_gc> *src_vr = src_trans->m_vr;
|
||||||
vec<ipa_vr, va_gc> *&dst_vr
|
vec<ipa_vr, va_gc> *&dst_vr
|
||||||
= ipcp_get_transformation_summary (dst)->m_vr;
|
= ipcp_get_transformation_summary (dst)->m_vr;
|
||||||
|
@ -3791,18 +3981,6 @@ ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
|
||||||
dst_vr->quick_push ((*src_vr)[i]);
|
dst_vr->quick_push ((*src_vr)[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_trans && vec_safe_length (src_trans->bits) > 0)
|
|
||||||
{
|
|
||||||
ipcp_grow_transformations_if_necessary ();
|
|
||||||
src_trans = ipcp_get_transformation_summary (src);
|
|
||||||
const vec<ipa_bits, va_gc> *src_bits = src_trans->bits;
|
|
||||||
vec<ipa_bits, va_gc> *&dst_bits
|
|
||||||
= ipcp_get_transformation_summary (dst)->bits;
|
|
||||||
vec_safe_reserve_exact (dst_bits, src_bits->length ());
|
|
||||||
for (unsigned i = 0; i < src_bits->length (); ++i)
|
|
||||||
dst_bits->quick_push ((*src_bits)[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register our cgraph hooks if they are not already there. */
|
/* Register our cgraph hooks if they are not already there. */
|
||||||
|
@ -4718,21 +4896,21 @@ ipa_write_jump_function (struct output_block *ob,
|
||||||
}
|
}
|
||||||
|
|
||||||
bp = bitpack_create (ob->main_stream);
|
bp = bitpack_create (ob->main_stream);
|
||||||
bp_pack_value (&bp, jump_func->bits.known, 1);
|
bp_pack_value (&bp, !!jump_func->bits, 1);
|
||||||
streamer_write_bitpack (&bp);
|
streamer_write_bitpack (&bp);
|
||||||
if (jump_func->bits.known)
|
if (jump_func->bits)
|
||||||
{
|
{
|
||||||
streamer_write_widest_int (ob, jump_func->bits.value);
|
streamer_write_widest_int (ob, jump_func->bits->value);
|
||||||
streamer_write_widest_int (ob, jump_func->bits.mask);
|
streamer_write_widest_int (ob, jump_func->bits->mask);
|
||||||
}
|
}
|
||||||
bp_pack_value (&bp, jump_func->vr_known, 1);
|
bp_pack_value (&bp, !!jump_func->m_vr, 1);
|
||||||
streamer_write_bitpack (&bp);
|
streamer_write_bitpack (&bp);
|
||||||
if (jump_func->vr_known)
|
if (jump_func->m_vr)
|
||||||
{
|
{
|
||||||
streamer_write_enum (ob->main_stream, value_rang_type,
|
streamer_write_enum (ob->main_stream, value_rang_type,
|
||||||
VR_LAST, jump_func->m_vr.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->min, true);
|
||||||
stream_write_tree (ob, jump_func->m_vr.max, true);
|
stream_write_tree (ob, jump_func->m_vr->max, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4809,26 +4987,25 @@ ipa_read_jump_function (struct lto_input_block *ib,
|
||||||
bool bits_known = bp_unpack_value (&bp, 1);
|
bool bits_known = bp_unpack_value (&bp, 1);
|
||||||
if (bits_known)
|
if (bits_known)
|
||||||
{
|
{
|
||||||
jump_func->bits.known = true;
|
widest_int value = streamer_read_widest_int (ib);
|
||||||
jump_func->bits.value = streamer_read_widest_int (ib);
|
widest_int mask = streamer_read_widest_int (ib);
|
||||||
jump_func->bits.mask = streamer_read_widest_int (ib);
|
ipa_set_jfunc_bits (jump_func, value, mask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
jump_func->bits.known = false;
|
jump_func->bits = NULL;
|
||||||
|
|
||||||
struct bitpack_d vr_bp = streamer_read_bitpack (ib);
|
struct bitpack_d vr_bp = streamer_read_bitpack (ib);
|
||||||
bool vr_known = bp_unpack_value (&vr_bp, 1);
|
bool vr_known = bp_unpack_value (&vr_bp, 1);
|
||||||
if (vr_known)
|
if (vr_known)
|
||||||
{
|
{
|
||||||
jump_func->vr_known = true;
|
enum value_range_type type = streamer_read_enum (ib, value_range_type,
|
||||||
jump_func->m_vr.type = streamer_read_enum (ib,
|
|
||||||
value_range_type,
|
|
||||||
VR_LAST);
|
VR_LAST);
|
||||||
jump_func->m_vr.min = stream_read_tree (ib, data_in);
|
tree min = stream_read_tree (ib, data_in);
|
||||||
jump_func->m_vr.max = stream_read_tree (ib, data_in);
|
tree max = stream_read_tree (ib, data_in);
|
||||||
|
ipa_set_jfunc_vr (jump_func, type, min, max);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
jump_func->vr_known = false;
|
jump_func->m_vr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
|
/* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
|
||||||
|
@ -5207,14 +5384,14 @@ write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i)
|
for (unsigned i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
const ipa_bits& bits_jfunc = (*ts->bits)[i];
|
const ipa_bits *bits_jfunc = (*ts->bits)[i];
|
||||||
struct bitpack_d bp = bitpack_create (ob->main_stream);
|
struct bitpack_d bp = bitpack_create (ob->main_stream);
|
||||||
bp_pack_value (&bp, bits_jfunc.known, 1);
|
bp_pack_value (&bp, !!bits_jfunc, 1);
|
||||||
streamer_write_bitpack (&bp);
|
streamer_write_bitpack (&bp);
|
||||||
if (bits_jfunc.known)
|
if (bits_jfunc)
|
||||||
{
|
{
|
||||||
streamer_write_widest_int (ob, bits_jfunc.value);
|
streamer_write_widest_int (ob, bits_jfunc->value);
|
||||||
streamer_write_widest_int (ob, bits_jfunc.mask);
|
streamer_write_widest_int (ob, bits_jfunc->mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5281,13 +5458,14 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ipa_bits& bits_jfunc = (*ts->bits)[i];
|
|
||||||
struct bitpack_d bp = streamer_read_bitpack (ib);
|
struct bitpack_d bp = streamer_read_bitpack (ib);
|
||||||
bits_jfunc.known = bp_unpack_value (&bp, 1);
|
bool known = bp_unpack_value (&bp, 1);
|
||||||
if (bits_jfunc.known)
|
if (known)
|
||||||
{
|
{
|
||||||
bits_jfunc.value = streamer_read_widest_int (ib);
|
ipa_bits *bits
|
||||||
bits_jfunc.mask = streamer_read_widest_int (ib);
|
= ipa_get_ipa_bits_for_value (streamer_read_widest_int (ib),
|
||||||
|
streamer_read_widest_int (ib));
|
||||||
|
(*ts->bits)[i] = bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5554,7 +5732,7 @@ ipcp_update_bits (struct cgraph_node *node)
|
||||||
if (!ts || vec_safe_length (ts->bits) == 0)
|
if (!ts || vec_safe_length (ts->bits) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vec<ipa_bits, va_gc> &bits = *ts->bits;
|
vec<ipa_bits *, va_gc> &bits = *ts->bits;
|
||||||
unsigned count = bits.length ();
|
unsigned count = bits.length ();
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i, parm = next_parm)
|
for (unsigned i = 0; i < count; ++i, parm = next_parm)
|
||||||
|
@ -5566,8 +5744,9 @@ ipcp_update_bits (struct cgraph_node *node)
|
||||||
gcc_checking_assert (parm);
|
gcc_checking_assert (parm);
|
||||||
next_parm = DECL_CHAIN (parm);
|
next_parm = DECL_CHAIN (parm);
|
||||||
|
|
||||||
if (!bits[i].known
|
if (!bits[i]
|
||||||
|| !(INTEGRAL_TYPE_P (TREE_TYPE (parm)) || POINTER_TYPE_P (TREE_TYPE (parm)))
|
|| !(INTEGRAL_TYPE_P (TREE_TYPE (parm))
|
||||||
|
|| POINTER_TYPE_P (TREE_TYPE (parm)))
|
||||||
|| !is_gimple_reg (parm))
|
|| !is_gimple_reg (parm))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -5578,7 +5757,7 @@ ipcp_update_bits (struct cgraph_node *node)
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
{
|
{
|
||||||
fprintf (dump_file, "Adjusting mask for param %u to ", i);
|
fprintf (dump_file, "Adjusting mask for param %u to ", i);
|
||||||
print_hex (bits[i].mask, dump_file);
|
print_hex (bits[i]->mask, dump_file);
|
||||||
fprintf (dump_file, "\n");
|
fprintf (dump_file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5587,14 +5766,14 @@ ipcp_update_bits (struct cgraph_node *node)
|
||||||
unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
|
unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
|
||||||
signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
|
signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
|
||||||
|
|
||||||
wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED)
|
wide_int nonzero_bits = wide_int::from (bits[i]->mask, prec, UNSIGNED)
|
||||||
| wide_int::from (bits[i].value, prec, sgn);
|
| wide_int::from (bits[i]->value, prec, sgn);
|
||||||
set_nonzero_bits (ddef, nonzero_bits);
|
set_nonzero_bits (ddef, nonzero_bits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned tem = bits[i].mask.to_uhwi ();
|
unsigned tem = bits[i]->mask.to_uhwi ();
|
||||||
unsigned HOST_WIDE_INT bitpos = bits[i].value.to_uhwi ();
|
unsigned HOST_WIDE_INT bitpos = bits[i]->value.to_uhwi ();
|
||||||
unsigned align = tem & -tem;
|
unsigned align = tem & -tem;
|
||||||
unsigned misalign = bitpos & (align - 1);
|
unsigned misalign = bitpos & (align - 1);
|
||||||
|
|
||||||
|
@ -5757,3 +5936,5 @@ ipcp_transform_function (struct cgraph_node *node)
|
||||||
else
|
else
|
||||||
return TODO_update_ssa_only_virtuals;
|
return TODO_update_ssa_only_virtuals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "gt-ipa-prop.h"
|
||||||
|
|
|
@ -152,11 +152,10 @@ struct GTY(()) ipa_bits
|
||||||
Similar to ccp_lattice_t, if xth bit of mask is 0,
|
Similar to ccp_lattice_t, if xth bit of mask is 0,
|
||||||
implies xth bit of value is constant. */
|
implies xth bit of value is constant. */
|
||||||
widest_int mask;
|
widest_int mask;
|
||||||
/* True if jump function is known. */
|
|
||||||
bool known;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Info about value ranges. */
|
/* Info about value ranges. */
|
||||||
|
|
||||||
struct GTY(()) ipa_vr
|
struct GTY(()) ipa_vr
|
||||||
{
|
{
|
||||||
/* The data fields below are valid only if known is true. */
|
/* The data fields below are valid only if known is true. */
|
||||||
|
@ -175,13 +174,15 @@ struct GTY (()) ipa_jump_func
|
||||||
description. */
|
description. */
|
||||||
struct ipa_agg_jump_function agg;
|
struct ipa_agg_jump_function agg;
|
||||||
|
|
||||||
/* Information about zero/non-zero bits. */
|
/* Information about zero/non-zero bits. The pointed to structure is shared
|
||||||
struct ipa_bits bits;
|
betweed different jump functions. Use ipa_set_jfunc_bits to set this
|
||||||
|
field. */
|
||||||
|
struct ipa_bits *bits;
|
||||||
|
|
||||||
/* Information about value range, containing valid data only when vr_known is
|
/* Information about value range, containing valid data only when vr_known is
|
||||||
true. */
|
true. The pointed to structure is shared betweed different jump
|
||||||
value_range m_vr;
|
functions. Use ipa_set_jfunc_vr to set this field. */
|
||||||
bool vr_known;
|
struct value_range *m_vr;
|
||||||
|
|
||||||
enum jump_func_type type;
|
enum jump_func_type type;
|
||||||
/* Represents a value of a jump function. pass_through is used only in jump
|
/* Represents a value of a jump function. pass_through is used only in jump
|
||||||
|
@ -547,7 +548,7 @@ struct GTY(()) ipcp_transformation_summary
|
||||||
/* Linked list of known aggregate values. */
|
/* Linked list of known aggregate values. */
|
||||||
ipa_agg_replacement_value *agg_values;
|
ipa_agg_replacement_value *agg_values;
|
||||||
/* Known bits information. */
|
/* Known bits information. */
|
||||||
vec<ipa_bits, va_gc> *bits;
|
vec<ipa_bits *, va_gc> *bits;
|
||||||
/* Value range information. */
|
/* Value range information. */
|
||||||
vec<ipa_vr, va_gc> *m_vr;
|
vec<ipa_vr, va_gc> *m_vr;
|
||||||
};
|
};
|
||||||
|
@ -630,6 +631,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
|
||||||
/* Creating and freeing ipa_node_params and ipa_edge_args. */
|
/* Creating and freeing ipa_node_params and ipa_edge_args. */
|
||||||
void ipa_create_all_node_params (void);
|
void ipa_create_all_node_params (void);
|
||||||
void ipa_create_all_edge_args (void);
|
void ipa_create_all_edge_args (void);
|
||||||
|
void ipa_check_create_edge_args (void);
|
||||||
void ipa_free_edge_args_substructures (struct ipa_edge_args *);
|
void ipa_free_edge_args_substructures (struct ipa_edge_args *);
|
||||||
void ipa_free_all_node_params (void);
|
void ipa_free_all_node_params (void);
|
||||||
void ipa_free_all_edge_args (void);
|
void ipa_free_all_edge_args (void);
|
||||||
|
@ -651,17 +653,6 @@ ipa_check_create_node_params (void)
|
||||||
ipa_node_params_t (symtab, true));
|
ipa_node_params_t (symtab, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function ensures the array of edge arguments infos is big enough to
|
|
||||||
accommodate a structure for all edges and reallocates it if not. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
ipa_check_create_edge_args (void)
|
|
||||||
{
|
|
||||||
if (vec_safe_length (ipa_edge_args_vector)
|
|
||||||
<= (unsigned) symtab->edges_max_uid)
|
|
||||||
vec_safe_grow_cleared (ipa_edge_args_vector, symtab->edges_max_uid + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if the array of edge infos is large enough to accommodate an
|
/* Returns true if the array of edge infos is large enough to accommodate an
|
||||||
info for EDGE. The main purpose of this function is that debug dumping
|
info for EDGE. The main purpose of this function is that debug dumping
|
||||||
function can check info availability without causing reallocations. */
|
function can check info availability without causing reallocations. */
|
||||||
|
@ -703,6 +694,9 @@ tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
|
||||||
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
|
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
|
||||||
bool speculative = false);
|
bool speculative = false);
|
||||||
tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
|
tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
|
||||||
|
ipa_bits *ipa_get_ipa_bits_for_value (const widest_int &value,
|
||||||
|
const widest_int &mask);
|
||||||
|
|
||||||
|
|
||||||
/* Functions related to both. */
|
/* Functions related to both. */
|
||||||
void ipa_analyze_node (struct cgraph_node *);
|
void ipa_analyze_node (struct cgraph_node *);
|
||||||
|
|
|
@ -24,7 +24,7 @@ enum value_range_type { VR_UNDEFINED, VR_RANGE,
|
||||||
|
|
||||||
/* Range of values that can be associated with an SSA_NAME after VRP
|
/* Range of values that can be associated with an SSA_NAME after VRP
|
||||||
has executed. */
|
has executed. */
|
||||||
struct GTY(()) value_range
|
struct GTY((for_user)) value_range
|
||||||
{
|
{
|
||||||
/* Lattice value represented by this range. */
|
/* Lattice value represented by this range. */
|
||||||
enum value_range_type type;
|
enum value_range_type type;
|
||||||
|
|
Loading…
Reference in New Issue