This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR58477, part I


Hi,
this patch fixes first part of PR58477.  Here we miss IPA devirtualization opurtunity but
produce speculative call.  Later during inlining, the standard folders produce direct call
and we ICE after cgraph_clone_edge messes up the speculative call info.

This patch makes cgraph_clone_edge to do the right thing.  We however should fix 
the missed optimization, too.

The testcase (I am not comitting since I want to deal with it incrementally is):
Index: testsuite/g++.dg/torture/pr58477.C
===================================================================
--- testsuite/g++.dg/torture/pr58477.C	(revision 0)
+++ testsuite/g++.dg/torture/pr58477.C	(revision 0)
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+struct A {
+  void operator==(const A &);
+};
+class B {
+public:
+  A m_fn1();
+  A m_fn2();
+};
+template <typename T, typename M> class C {
+public:
+  T Key;
+  const M &m_fn2(const T &);
+  virtual void m_fn1() {}
+  B _map;
+};
+
+C<int, int> b;
+template <typename T, typename M> const M &C<T, M>::m_fn2(const T &) {
+  A a = _map.m_fn2();
+  a == _map.m_fn1();
+  m_fn1();
+}
+
+void fn1() { b.m_fn2(0); }

And code in question:

;; Function const M& C<T, M>::m_fn2(const T&) [with T = int; M = int] (_ZN1CIiiE5m_fn2ERKi.isra.0, funcdef_no=10, decl_uid=2371, symbol_order=19)

const M& C<T, M>::m_fn2(const T&) [with T = int; M = int] (struct C * const this)
{
  struct A D.2376;
  struct A a;
  struct B * _2;
  int (*__vtbl_ptr_type) () * _3;
  int (*__vtbl_ptr_type) () _4;

  <bb 2>:
  _2 = &this_1(D)->_map;
  B::m_fn2 (_2);
  B::m_fn1 (_2);
  A::operator== (&a, &D.2376);
  D.2376 ={v} {CLOBBER};
  _3 = this_1(D)->_vptr.C;
  _4 = *_3;
  OBJ_TYPE_REF(_4;(struct C)this_1(D)->0) (this_1(D));
  a ={v} {CLOBBER};
  return;

}
Where this is propagated into &b that is a static variable of given type.
The reason why ipa-cp does not match is that it thinks the type may 
dynamically change.  I think it can not since the function is method and
I do not think methods except for ctors/dtors should have way to change
type of their object.  Martin, Jason, is there way to implement this logic
into detect_type_change?

In any case the stopper here is:
  D.2376 ={v} {CLOBBER};
that is stupid.  I am testing followup patch that makes type change machinery
to walk through clobbers.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

	* cgraphclones.c (cgraph_clone_edge): Do not resolve speculative edges.
Index: cgraphclones.c
===================================================================
--- cgraphclones.c	(revision 205987)
+++ cgraphclones.c	(working copy)
@@ -123,7 +123,10 @@ cgraph_clone_edge (struct cgraph_edge *e
     {
       tree decl;
 
-      if (call_stmt && (decl = gimple_call_fndecl (call_stmt)))
+      if (call_stmt && (decl = gimple_call_fndecl (call_stmt))
+	  /* When the call is speculative, we need to resolve it 
+	     via cgraph_resolve_speculation and not here.  */
+	  && !e->speculative)
 	{
 	  struct cgraph_node *callee = cgraph_get_node (decl);
 	  gcc_checking_assert (callee);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]