Commit 7e9f2b6e by Martin Jambor Committed by Martin Jambor

re PR tree-optimization/55260 (ICE: in ipa_get_parm_lattices, at ipa-cp.c:263…

re PR tree-optimization/55260 (ICE: in ipa_get_parm_lattices, at ipa-cp.c:263 with -O2 -fno-inline -fipa-cp-clone)

2012-11-21  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/55260
	* ipa-cp.c (intersect_aggregates_with_edge): New function.
	(find_aggregate_values_for_callers_subset): Part moved to the function
	above.  Call it.
	(cgraph_edge_brings_all_agg_vals_for_node): Reimplemented using
	intersect_aggregates_with_edge.

	* testsuite/g++.dg/torture/pr55260-2.C: New test.

From-SVN: r193700
parent 3358fd40
2012-11-21 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/55260
* ipa-cp.c (intersect_aggregates_with_edge): New function.
(find_aggregate_values_for_callers_subset): Part moved to the function
above. Call it.
(cgraph_edge_brings_all_agg_vals_for_node): Reimplemented using
intersect_aggregates_with_edge.
2012-11-21 Matthias Klose <doko@ubuntu.com>
* config/s390/t-linux64: Add multiarch names in MULTILIB_OSDIRNAMES.
......@@ -2850,41 +2850,17 @@ intersect_with_agg_replacements (struct cgraph_node *node, int index,
}
}
/* Look at edges in CALLERS and collect all known aggregate values that arrive
from all of them. */
/* Intersect values in INTER with aggregate values that come along edge CS to
parameter number INDEX and return it. If INTER does not actually exist yet,
copy all incoming values to it. If we determine we ended up with no values
whatsoever, return a released vector. */
static struct ipa_agg_replacement_value *
find_aggregate_values_for_callers_subset (struct cgraph_node *node,
vec<cgraph_edge_p> callers)
static vec<ipa_agg_jf_item_t>
intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
vec<ipa_agg_jf_item_t> inter)
{
struct ipa_node_params *dest_info = IPA_NODE_REF (node);
struct ipa_agg_replacement_value *res = NULL;
struct cgraph_edge *cs;
int i, j, count = ipa_get_param_count (dest_info);
FOR_EACH_VEC_ELT (callers, j, cs)
{
int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
if (c < count)
count = c;
}
for (i = 0; i < count ; i++)
{
struct cgraph_edge *cs;
vec<ipa_agg_jf_item_t> inter = vNULL;
struct ipa_agg_jf_item *item;
int j;
/* Among other things, the following check should deal with all by_ref
mismatches. */
if (ipa_get_parm_lattices (dest_info, i)->aggs_bottom)
continue;
FOR_EACH_VEC_ELT (callers, j, cs)
{
struct ipa_jump_func *jfunc;
jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
if (jfunc->type == IPA_JF_PASS_THROUGH
&& ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
{
......@@ -2935,7 +2911,7 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node,
if (!inter.exists ())
inter = agg_replacements_to_vector (cs->caller, delta);
else
intersect_with_agg_replacements (cs->caller, i, &inter,
intersect_with_agg_replacements (cs->caller, index, &inter,
delta);
}
else
......@@ -2952,6 +2928,7 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node,
}
else if (jfunc->agg.items)
{
struct ipa_agg_jf_item *item;
int k;
if (!inter.exists ())
......@@ -2987,7 +2964,47 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node,
}
}
else
goto next_param;
{
inter.release();
return vec<ipa_agg_jf_item_t>();
}
return inter;
}
/* Look at edges in CALLERS and collect all known aggregate values that arrive
from all of them. */
static struct ipa_agg_replacement_value *
find_aggregate_values_for_callers_subset (struct cgraph_node *node,
vec<cgraph_edge_p> callers)
{
struct ipa_node_params *dest_info = IPA_NODE_REF (node);
struct ipa_agg_replacement_value *res = NULL;
struct cgraph_edge *cs;
int i, j, count = ipa_get_param_count (dest_info);
FOR_EACH_VEC_ELT (callers, j, cs)
{
int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
if (c < count)
count = c;
}
for (i = 0; i < count ; i++)
{
struct cgraph_edge *cs;
vec<ipa_agg_jf_item_t> inter = vNULL;
struct ipa_agg_jf_item *item;
int j;
/* Among other things, the following check should deal with all by_ref
mismatches. */
if (ipa_get_parm_lattices (dest_info, i)->aggs_bottom)
continue;
FOR_EACH_VEC_ELT (callers, j, cs)
{
inter = intersect_aggregates_with_edge (cs, i, inter);
if (!inter.exists ())
goto next_param;
......@@ -3079,37 +3096,63 @@ static bool
cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
struct cgraph_node *node)
{
struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
struct ipa_node_params *orig_caller_info = IPA_NODE_REF (cs->caller);
struct ipa_agg_replacement_value *aggval;
int i, ec, count;
aggval = ipa_get_agg_replacements_for_node (node);
while (aggval)
{
bool found = false;
struct ipcp_param_lattices *plats;
plats = ipa_get_parm_lattices (caller_info, aggval->index);
if (plats->aggs_bottom || plats->aggs_contain_variable)
if (!aggval)
return true;
count = ipa_get_param_count (IPA_NODE_REF (node));
ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
if (ec < count)
for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
if (aggval->index >= ec)
return false;
for (struct ipcp_agg_lattice *aglat = plats->aggs;
aglat;
aglat = aglat->next)
if (aglat->offset == aggval->offset)
if (orig_caller_info->ipcp_orig_node)
orig_caller_info = IPA_NODE_REF (orig_caller_info->ipcp_orig_node);
for (i = 0; i < count; i++)
{
if (ipa_lat_is_single_const (aglat)
&& values_equal_for_ipcp_p (aggval->value,
aglat->values->value))
static vec<ipa_agg_jf_item_t> values = vec<ipa_agg_jf_item_t>();
struct ipcp_param_lattices *plats;
bool interesting = false;
for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
if (aggval->index == i)
{
found = true;
interesting = true;
break;
}
else
if (!interesting)
continue;
plats = ipa_get_parm_lattices (orig_caller_info, aggval->index);
if (plats->aggs_bottom)
return false;
}
if (!found)
values = intersect_aggregates_with_edge (cs, i, values);
if (!values.exists())
return false;
aggval = aggval->next;
for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
if (aggval->index == i)
{
struct ipa_agg_jf_item *item;
int j;
bool found = false;
FOR_EACH_VEC_ELT (values, j, item)
if (item->value
&& item->offset == av->offset
&& values_equal_for_ipcp_p (item->value, av->value))
found = true;
if (!found)
{
values.release();
return false;
}
}
}
return true;
}
......
2012-11-21 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/55260
* g++.dg/torture/pr55260-2.C: New test.
2012-11-21 Martin Jambor <mjambor@suse.cz>
* gcc.dg/torture/pr55238.c: Remove hidden attribute.
2012-11-21 Bin Cheng <bin.cheng@arm.com>
......
/* { dg-do compile } */
/* { dg-add-options bind_pic_locally } */
struct B
{
virtual void test_suite_finish ();
};
void
fn1 (B & p2)
{
fn1 (p2);
B & a = p2;
a.test_suite_finish ();
B b;
fn1 (b);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment