Commit 4517b378 by Martin Jambor Committed by Martin Jambor

[PR 89330] Remove non-useful speculations from new_edges

2019-07-26  Martin Jambor  <mjambor@suse.cz>

	PR ipa/89330
	* ipa-inline-transform.c (check_speculations_1): New function.
	(push_all_edges_in_set_to_vec): Likewise.
	(check_speculations): Use check_speculations_1, new parameter
	new_edges.
	(inline_call): Pass new_edges to check_speculations.
	* ipa-inline.c (add_new_edges_to_heap): Assert edge_callee is not
	NULL.
	(speculation_useful_p): Early return true if edge is inlined, remove
	later checks for inline_failed.

	testsuite/
	* g++.dg/lto/pr89330_[01].C: New test.
	* g++.dg/tree-prof/devirt.C: Added -fno-profile-values to dg-options.

From-SVN: r273825
parent ac2dca4d
2019-07-26 Martin Jambor <mjambor@suse.cz>
PR ipa/89330
* ipa-inline-transform.c (check_speculations_1): New function.
(push_all_edges_in_set_to_vec): Likewise.
(check_speculations): Use check_speculations_1, new parameter
new_edges.
(inline_call): Pass new_edges to check_speculations.
* ipa-inline.c (add_new_edges_to_heap): Assert edge_callee is not
NULL.
(speculation_useful_p): Early return true if edge is inlined, remove
later checks for inline_failed.
2019-07-25 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/91223
......
......@@ -237,10 +237,13 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
}
}
/* Check all speculations in N and resolve them if they seems useless. */
/* Check all speculations in N and if any seem useless, resolve them. When a
first edge is resolved, pop all edges from NEW_EDGES and insert them to
EDGE_SET. Then remove each resolved edge from EDGE_SET, if it is there. */
static bool
check_speculations (cgraph_node *n)
check_speculations_1 (cgraph_node *n, vec<cgraph_edge *> *new_edges,
hash_set <cgraph_edge *> *edge_set)
{
bool speculation_removed = false;
cgraph_edge *next;
......@@ -250,15 +253,46 @@ check_speculations (cgraph_node *n)
next = e->next_callee;
if (e->speculative && !speculation_useful_p (e, true))
{
while (new_edges && !new_edges->is_empty ())
edge_set->add (new_edges->pop ());
edge_set->remove (e);
e->resolve_speculation (NULL);
speculation_removed = true;
}
else if (!e->inline_failed)
speculation_removed |= check_speculations (e->callee);
speculation_removed |= check_speculations_1 (e->callee, new_edges,
edge_set);
}
return speculation_removed;
}
/* Push E to NEW_EDGES. Called from hash_set traverse method, which
unfortunately means this function has to have external linkage, otherwise
the code will not compile with gcc 4.8. */
bool
push_all_edges_in_set_to_vec (cgraph_edge * const &e,
vec<cgraph_edge *> *new_edges)
{
new_edges->safe_push (e);
return true;
}
/* Check all speculations in N and if any seem useless, resolve them and remove
them from NEW_EDGES. */
static bool
check_speculations (cgraph_node *n, vec<cgraph_edge *> *new_edges)
{
hash_set <cgraph_edge *> edge_set;
bool res = check_speculations_1 (n, new_edges, &edge_set);
if (!edge_set.is_empty ())
edge_set.traverse <vec<cgraph_edge *> *,
push_all_edges_in_set_to_vec> (new_edges);
return res;
}
/* Mark all call graph edges coming out of NODE and all nodes that have been
inlined to it as in_polymorphic_cdtor. */
......@@ -450,7 +484,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
mark_all_inlined_calls_cdtor (e->callee);
if (opt_for_fn (e->caller->decl, optimize))
new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
check_speculations (e->callee);
check_speculations (e->callee, new_edges);
if (update_overall_summary)
ipa_update_overall_fn_summary (to);
else
......
......@@ -1629,6 +1629,7 @@ add_new_edges_to_heap (edge_heap_t *heap, vec<cgraph_edge *> new_edges)
struct cgraph_edge *edge = new_edges.pop ();
gcc_assert (!edge->aux);
gcc_assert (edge->callee);
if (edge->inline_failed
&& can_inline_edge_p (edge, true)
&& want_inline_small_function_p (edge, true)
......@@ -1656,6 +1657,10 @@ heap_edge_removal_hook (struct cgraph_edge *e, void *data)
bool
speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
{
/* If we have already decided to inline the edge, it seems useful. */
if (!e->inline_failed)
return true;
enum availability avail;
struct cgraph_node *target = e->callee->ultimate_alias_target (&avail,
e->caller);
......@@ -1690,12 +1695,11 @@ speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
to an ipa-cp clone (that are seen by having local flag set),
it is probably pointless to inline it unless hardware is missing
indirect call predictor. */
if (!anticipate_inlining && e->inline_failed && !target->local.local)
if (!anticipate_inlining && !target->local.local)
return false;
/* For overwritable targets there is not much to do. */
if (e->inline_failed
&& (!can_inline_edge_p (e, false)
|| !can_inline_edge_by_limits_p (e, false, true)))
if (!can_inline_edge_p (e, false)
|| !can_inline_edge_by_limits_p (e, false, true))
return false;
/* OK, speculation seems interesting. */
return true;
......
2019-07-26 Martin Jambor <mjambor@suse.cz>
PR ipa/89330
* g++.dg/lto/pr89330_[01].C: New test.
* g++.dg/tree-prof/devirt.C: Added -fno-profile-values to dg-options.
2019-07-25 Martin Sebor <msebor@redhat.com>
PR tree-optimization/91183
......
// { dg-lto-do link }
// { dg-lto-options { { -O3 -g -flto -shared -Wno-odr } } }
namespace Inkscape {
class Anchored {};
namespace XML {
enum NodeType {};
class Node :Anchored {
public:
virtual NodeType type() ;
virtual char name() ;
virtual int code() ;
virtual unsigned position() ;
virtual unsigned childCount() ;
virtual char content() ;
virtual char *attribute() const ;
virtual int attributeList() ;
virtual bool matchAttributeName() ;
virtual void setPosition() ;
virtual void setContent() ;
virtual void setAttribute() ;
virtual int document() ;
virtual int document() const ;
virtual Node *root() ;
virtual Node *root() const ;
virtual Node *parent() ;
virtual Node *next() const ;
virtual Node *firstChild() const ;
};
} } struct rdf_license_t {
};
;
class RDFImpl {
;
rdf_license_t *getLicense();
};
static bool rdf_match_license(Inkscape::XML::Node const *repr) {
for (Inkscape::XML::Node *current = repr->firstChild(); current;
current->next()->attribute());
return 0;
}
rdf_license_t *RDFImpl::getLicense() {
Inkscape::XML::Node *repr ;
for (rdf_license_t *license ; license;
license) {
rdf_match_license(repr);
}
return 0;
}
typedef char gchar;
namespace Inkscape {
class Anchored {
int _anchor;
};
namespace XML {
enum NodeType {};
class Node :Anchored {
virtual NodeType type() ;
virtual char const *name() const ;
virtual int code() ;
virtual unsigned position() ;
virtual unsigned childCount() ;
virtual char content() ;
virtual char attribute() ;
virtual int attributeList() ;
virtual bool matchAttributeName() ;
virtual void setPosition() ;
virtual void setContent() ;
virtual int document() ;
virtual int document() const ;
virtual Node *root() ;
virtual Node *root() const ;
virtual Node *parent() ;
virtual Node *parent() const ;
virtual Node *next() ;
virtual Node const *next() const ;
};
class SimpleNode : virtual Node {
char const *name() const;
Node *next() const { return _next; }
SimpleNode *_next;
};
gchar const *SimpleNode::name() const { return 0; }
} }
/* PR ipa/88561 */
/* { dg-options "-O3 -fdump-tree-tracer-details -fdump-tree-dom3-details" } */
/* { dg-options "-O3 -fdump-tree-tracer-details -fdump-tree-dom3-details -fno-profile-values" } */
struct nsISupports
{
......
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