OSDN Git Service

2014-04-07 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Apr 2014 09:54:55 +0000 (09:54 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Apr 2014 09:54:55 +0000 (09:54 +0000)
PR ipa/60640
* ipa-cp.c (propagate_constants_accross_call): Do not propagate
accross thunks.

testsuite/
        * g++.dg/ipa/pr60640-1.C: New test.
        * g++.dg/ipa/pr60640-2.C: Likewise.
        * g++.dg/ipa/pr60640-3.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@209181 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ipa-cp.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr60640-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ipa/pr60640-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ipa/pr60640-3.C [new file with mode: 0644]

index 8177c04..27001a1 100644 (file)
@@ -1,3 +1,9 @@
+2014-04-07  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/60640
+       * ipa-cp.c (propagate_constants_accross_call): Do not propagate
+       accross thunks.
+
 2014-04-07  Dominique d'Humieres <dominiq@lps.ens.fr>    
 
        Backport from mainline
index 454283a..ddf6605 100644 (file)
@@ -1063,21 +1063,21 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
   args_count = ipa_get_cs_argument_count (args);
   parms_count = ipa_get_param_count (callee_info);
 
-  /* If this call goes through a thunk we must not propagate to the first (0th)
-     parameter.  However, we might need to uncover a thunk from below a series
-     of aliases first.  */
+  /* If this call goes through a thunk we should not propagate because we
+     cannot redirect edges to thunks.  However, we might need to uncover a
+     thunk from below a series of aliases first.  */
   alias_or_thunk = cs->callee;
   while (alias_or_thunk->alias)
     alias_or_thunk = cgraph_alias_aliased_node (alias_or_thunk);
   if (alias_or_thunk->thunk.thunk_p)
     {
-      ret |= set_lattice_contains_variable (ipa_get_lattice (callee_info, 0));
-      i = 1;
+      for (i = 0; i < parms_count; i++)
+       ret |= set_lattice_contains_variable (ipa_get_lattice (callee_info, i));
+
+      return ret;
     }
-  else
-    i = 0;
 
-  for (; (i < args_count) && (i < parms_count); i++)
+  for (i = 0; (i < args_count) && (i < parms_count); i++)
     {
       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
       struct ipcp_lattice *dest_lat = ipa_get_lattice (callee_info, i);
index 7587891..e8b525c 100644 (file)
@@ -1,3 +1,10 @@
+2014-04-07  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/60640
+        * g++.dg/ipa/pr60640-1.C: New test.
+        * g++.dg/ipa/pr60640-2.C: Likewise.
+        * g++.dg/ipa/pr60640-3.C: Likewise.
+
 2014-04-06  Dominique d'Humieres  <dominiq@lps.ens.fr>
            Iain Sandoe <iain@codesourcery.com>
 
diff --git a/gcc/testsuite/g++.dg/ipa/pr60640-1.C b/gcc/testsuite/g++.dg/ipa/pr60640-1.C
new file mode 100644 (file)
index 0000000..7a0b918
--- /dev/null
@@ -0,0 +1,50 @@
+// { dg-do compile }
+// { dg-options "-O3" }
+
+class ASN1Object
+{
+public:
+  virtual ~ASN1Object ();
+};
+class A
+{
+  virtual unsigned m_fn1 () const;
+};
+class B
+{
+public:
+  ASN1Object Element;
+  virtual unsigned m_fn1 (bool) const;
+};
+template <class BASE> class C : public BASE
+{
+};
+
+class D : ASN1Object, public B
+{
+};
+class G : public D
+{
+  unsigned m_fn1 (bool) const {}
+};
+class F : A
+{
+public:
+  F (A);
+  unsigned m_fn1 () const
+  {
+    int a;
+    a = m_fn2 ().m_fn1 (0);
+    return a;
+  }
+  const B &m_fn2 () const { return m_groupParameters; }
+  C<G> m_groupParameters;
+};
+template <class D> void BenchMarkKeyAgreement (int *, int *, int)
+{
+  A f;
+  D d (f);
+}
+
+void BenchmarkAll2 () { BenchMarkKeyAgreement<F>(0, 0, 0); }
+
diff --git a/gcc/testsuite/g++.dg/ipa/pr60640-2.C b/gcc/testsuite/g++.dg/ipa/pr60640-2.C
new file mode 100644 (file)
index 0000000..c6e614c
--- /dev/null
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-options "-O3" }
+
+struct B { virtual unsigned f () const; };
+struct C { virtual void f (); };
+struct F { virtual unsigned f (bool) const; ~F (); };
+struct J : C, F {};
+struct G : J { unsigned f (bool) const { return 0; } };
+struct H : B
+{
+  H (int);
+  unsigned f () const { return ((const F &) h).f (0); }
+  G h;
+};
+H h (0);
diff --git a/gcc/testsuite/g++.dg/ipa/pr60640-3.C b/gcc/testsuite/g++.dg/ipa/pr60640-3.C
new file mode 100644 (file)
index 0000000..21b1f58
--- /dev/null
@@ -0,0 +1,81 @@
+// { dg-do run }
+// { dg-options "-O3" }
+
+struct Distraction
+{
+  char fc[8];
+  virtual Distraction * return_self ()
+  { return this; }
+};
+
+namespace {
+
+struct A;
+static A * __attribute__ ((noinline, noclone)) get_an_A ();
+
+static int go;
+
+struct A
+{
+  int fi;
+
+  A () : fi(777) {}
+  A (int pi) : fi (pi) {}
+  virtual A * foo (int p) = 0;
+};
+
+struct B;
+static B * __attribute__ ((noinline, noclone)) get_a_B ();
+
+struct B : public Distraction, A
+{
+  B () : Distraction(), A() { }
+  B (int pi) : Distraction (), A (pi) {}
+  virtual B * foo (int p)
+  {
+    int o = fi;
+    for (int i = 0; i < p; i++)
+      o += i + i * i;
+    go = o;
+
+    return get_a_B ();
+  }
+};
+
+
+struct B gb1 (1111), gb2 (2);
+static B * __attribute__ ((noinline, noclone))
+get_a_B ()
+{
+  return &gb1;
+}
+
+static A * __attribute__ ((noinline, noclone))
+get_an_A ()
+{
+  return &gb2;
+}
+
+}
+
+static int __attribute__ ((noinline, noclone))
+get_a_number ()
+{
+  return 5;
+}
+
+extern "C" void abort (void);
+
+int main (int argc, char *argv[])
+{
+  for (int i = 0; i < get_a_number (); i++)
+    {
+      struct A *p = get_an_A ();
+      struct A *r = p->foo (4);
+      if (r->fi != 1111)
+       abort ();
+      if (go != 22)
+       abort ();
+    }
+  return 0;
+}