Commit df0d8136 by Jan Hubicka Committed by Jan Hubicka

* ipa-polymorphic-call.c

	(ipa_polymorphic_call_context::speculation_consistent_p): Constify.
	(ipa_polymorphic_call_context::meet_speculation_with): New function.
	(ipa_polymorphic_call_context::combine_with): Handle types in construction
	better.
	(ipa_polymorphic_call_context::equal_to): Do not bother about useless
	speculation.
	(ipa_polymorphic_call_context::meet_with): New function.
	* cgraph.h (class ipa_polymorphic_call_context): Add
	meet_width, meet_speculation_with; constify speculation_consistent_p.
	* ipa-cp.c (ipa_context_from_jfunc): Handle speculation; combine with incomming
	context.
	(propagate_context_accross_jump_function): Likewise; be more cureful.
	about set_contains_variable.
	(ipa_get_indirect_edge_target_1): Fix handling of dynamic type changes.
	(find_more_scalar_values_for_callers_subset): Fix.
	(find_more_contexts_for_caller_subset): Perform meet operation.

From-SVN: r217634
parent 70486010
2014-11-16 Jan Hubicka <hubicka@ucw.cz>
* ipa-polymorphic-call.c
(ipa_polymorphic_call_context::speculation_consistent_p): Constify.
(ipa_polymorphic_call_context::meet_speculation_with): New function.
(ipa_polymorphic_call_context::combine_with): Handle types in construction
better.
(ipa_polymorphic_call_context::equal_to): Do not bother about useless
speculation.
(ipa_polymorphic_call_context::meet_with): New function.
* cgraph.h (class ipa_polymorphic_call_context): Add
meet_width, meet_speculation_with; constify speculation_consistent_p.
* ipa-cp.c (ipa_context_from_jfunc): Handle speculation; combine with incomming
context.
(propagate_context_accross_jump_function): Likewise; be more cureful.
about set_contains_variable.
(ipa_get_indirect_edge_target_1): Fix handling of dynamic type changes.
(find_more_scalar_values_for_callers_subset): Fix.
(find_more_contexts_for_caller_subset): Perform meet operation.
2014-11-16 Jan Hubicka <hubicka@ucw.cz>
* passes.c (execute_one_pass): Do not apply all transforms prior
every simple IPA pass.
* cgraphunit.c: Do not include fibheap.h
......@@ -1389,6 +1389,7 @@ public:
If actual type the context is being used in is known, OTR_TYPE should be
set accordingly. This improves quality of combined result. */
bool combine_with (ipa_polymorphic_call_context, tree otr_type = NULL);
bool meet_with (ipa_polymorphic_call_context, tree otr_type = NULL);
/* Return TRUE if context is fully useless. */
bool useless_p () const;
......@@ -1406,9 +1407,10 @@ public:
private:
bool combine_speculation_with (tree, HOST_WIDE_INT, bool, tree);
bool meet_speculation_with (tree, HOST_WIDE_INT, bool, tree);
void set_by_decl (tree, HOST_WIDE_INT);
bool set_by_invariant (tree, tree, HOST_WIDE_INT);
bool speculation_consistent_p (tree, HOST_WIDE_INT, bool, tree);
bool speculation_consistent_p (tree, HOST_WIDE_INT, bool, tree) const;
void make_speculative (tree otr_type = NULL);
};
......
......@@ -946,17 +946,17 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
{
ipa_polymorphic_call_context srcctx;
int srcidx;
bool type_preserved = true;
if (jfunc->type == IPA_JF_PASS_THROUGH)
{
if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR
|| !ipa_get_jf_pass_through_type_preserved (jfunc))
if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
return ctx;
type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
srcidx = ipa_get_jf_pass_through_formal_id (jfunc);
}
else
{
if (!ipa_get_jf_ancestor_type_preserved (jfunc))
return ctx;
type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
srcidx = ipa_get_jf_ancestor_formal_id (jfunc);
}
if (info->ipcp_orig_node)
......@@ -981,7 +981,10 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
return ctx;
if (jfunc->type == IPA_JF_ANCESTOR)
srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc));
ctx.combine_with (srcctx);
if (!type_preserved)
srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
srcctx.combine_with (ctx);
return srcctx;
}
return ctx;
......@@ -1298,15 +1301,13 @@ propagate_context_accross_jump_function (cgraph_edge *cs,
return false;
bool ret = false;
bool added_sth = false;
bool type_preserved = true;
ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
= ipa_get_ith_polymorhic_call_context (args, idx);
if (edge_ctx_ptr)
{
edge_ctx = *edge_ctx_ptr;
edge_ctx.clear_speculation ();
}
edge_ctx = *edge_ctx_ptr;
if (jfunc->type == IPA_JF_PASS_THROUGH
|| jfunc->type == IPA_JF_ANCESTOR)
......@@ -1320,15 +1321,14 @@ propagate_context_accross_jump_function (cgraph_edge *cs,
not set instead of punting. */
if (jfunc->type == IPA_JF_PASS_THROUGH)
{
if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR
|| !ipa_get_jf_pass_through_type_preserved (jfunc))
if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
goto prop_fail;
type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
}
else
{
if (!ipa_get_jf_ancestor_type_preserved (jfunc))
goto prop_fail;
type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
}
......@@ -1338,21 +1338,24 @@ propagate_context_accross_jump_function (cgraph_edge *cs,
&& (src_lat->contains_variable
|| (src_lat->values_count > 1)))
goto prop_fail;
if (src_lat->contains_variable)
ret |= dest_lat->set_contains_variable ();
ipcp_value<ipa_polymorphic_call_context> *src_val;
for (src_val = src_lat->values; src_val; src_val = src_val->next)
{
ipa_polymorphic_call_context cur = src_val->value;
if (!type_preserved)
cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
if (jfunc->type == IPA_JF_ANCESTOR)
cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
/* TODO: Perhaps attempt to look up some used OTR type? */
cur.clear_speculation ();
if (!edge_ctx.useless_p ())
cur.combine_with (edge_ctx);
/* TODO: In cases we know how the context is going to be used,
we can improve the result by passing proper OTR_TYPE. */
cur.combine_with (edge_ctx);
if (!cur.useless_p ())
{
if (src_lat->contains_variable
&& !edge_ctx.equal_to (cur))
ret |= dest_lat->set_contains_variable ();
ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
added_sth = true;
}
......@@ -1848,6 +1851,10 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
if (known_contexts.length () > (unsigned int) param_index)
{
context = known_contexts[param_index];
context.offset_by (anc_offset);
if (ie->indirect_info->vptr_changed)
context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
ie->indirect_info->otr_type);
if (t)
{
ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
......@@ -3160,6 +3167,7 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
struct cgraph_edge *cs;
tree newval = NULL_TREE;
int j;
bool first = true;
if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
continue;
......@@ -3178,13 +3186,15 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func);
if (!t
|| (newval
&& !values_equal_for_ipcp_p (t, newval)))
&& !values_equal_for_ipcp_p (t, newval))
|| (!first && !newval))
{
newval = NULL_TREE;
break;
}
else
newval = t;
first = false;
}
if (newval)
......@@ -3226,7 +3236,7 @@ find_more_contexts_for_caller_subset (cgraph_node *node,
continue;
ipa_polymorphic_call_context newval;
bool found = false;
bool first = true;
int j;
FOR_EACH_VEC_ELT (callers, j, cs)
......@@ -3238,21 +3248,18 @@ find_more_contexts_for_caller_subset (cgraph_node *node,
ipa_polymorphic_call_context ctx;
ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
jfunc);
ctx.clear_speculation ();
if (ctx.useless_p ()
|| (found && !values_equal_for_ipcp_p (newval, ctx)))
{
found = false;
break;
}
else if (!found)
if (first)
{
found = true;
newval = ctx;
first = false;
}
else
newval.meet_with (ctx);
if (newval.useless_p ())
break;
}
if (found)
if (!newval.useless_p ())
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
......
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