]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR tree-optimization/57661
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Aug 2013 17:06:13 +0000 (17:06 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Aug 2013 17:06:13 +0000 (17:06 +0000)
* tree-inline.h (struct copy_body_data): Add blocks_to_copy field.
* tree-inline.c (tree_function_versioning): Initialize it.
(remap_gimple_stmt): Return GIMPLE_NOP for MEM_REF lhs clobber stmts
if id->blocks_to_copy and MEM_REF's SSA_NAME is defined in a block
that is not being copied.

* g++.dg/opt/pr57661.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201698 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr57661.C [new file with mode: 0644]
gcc/tree-inline.c
gcc/tree-inline.h

index 682328effbd94cbd2379c62e606178c66022eced..f22f848d0bb94309a75d666f3d328f2447836dd5 100644 (file)
@@ -1,5 +1,12 @@
 2013-08-13  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/57661
+       * tree-inline.h (struct copy_body_data): Add blocks_to_copy field.
+       * tree-inline.c (tree_function_versioning): Initialize it.
+       (remap_gimple_stmt): Return GIMPLE_NOP for MEM_REF lhs clobber stmts
+       if id->blocks_to_copy and MEM_REF's SSA_NAME is defined in a block
+       that is not being copied.
+
        PR sanitizer/56417
        * asan.c (instrument_strlen_call): Fix typo in comment.
        Use char * type even for the lhs of POINTER_PLUS_EXPR.
index 6e1b6309e7e8733cda3a7a39ea90e12af2e7ab41..f962249b233eefe2ff98d31373ec880975a2fd7b 100644 (file)
@@ -1,5 +1,8 @@
 2013-08-13  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/57661
+       * g++.dg/opt/pr57661.C: New test.
+
        PR sanitizer/56417
        * gcc.dg/asan/pr56417.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/opt/pr57661.C b/gcc/testsuite/g++.dg/opt/pr57661.C
new file mode 100644 (file)
index 0000000..8be9f09
--- /dev/null
@@ -0,0 +1,76 @@
+// PR tree-optimization/57661
+// { dg-do compile }
+// { dg-options "-O2 -fno-tree-forwprop -std=gnu++11" }
+
+template <typename>
+struct A
+{
+  ~A () {}
+};
+template <typename _Tp>
+using B = A <_Tp>;
+template <typename _Tp>
+class C : B <_Tp> {};
+namespace N { enum D { d }; }
+template <class>
+struct E
+{
+  ~E ();
+};
+template <class, class V>
+struct F : V {};
+template <class U, class V>
+struct G : F <U, V>
+{
+  N::D g1;
+  void g2 ();
+  void g3 ();
+  void g4 () { g3 (); }
+  static void g5 (G *__t) { __t->g4 (); }
+};
+template <class U, class V>
+struct H : G <U, V>
+{
+  E <U> *h1;
+  bool h2;
+  ~H () throw ()
+  {
+    this->g2 ();
+    if (h2)
+      delete h1;
+  }
+};
+template <class U, class V>
+struct I : H <U, V>, E <U>
+{
+  G <U, V> *i;
+  ~I () throw ()
+  {
+    i->g4 ();
+  }
+};
+struct J
+{
+  typedef C <char> j1;
+  typedef G <char, C <char>> j2;
+  J ();
+  j2 *j3;
+};
+struct K : J
+{
+  typedef G <char, C <char>> j2;
+  K () { j2::g5 (this->j3); }
+};
+template <class U, class V>
+void G <U, V>::g3 ()
+{
+  switch (g1)
+    {
+    case N::d:
+      {
+       I <U, V> *q = (I <U, V> *) this;
+       q->I <U, V>::~I ();
+      }
+    }
+}
+K r;
index 00e31982957ba59d3513e486a2590b8a9fcb8fc1..55e527014f1148de4842e4391a2a27f477e65a1f 100644 (file)
@@ -1387,6 +1387,23 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
            }
        }
 
+      /* For *ptr_N ={v} {CLOBBER}, if ptr_N is SSA_NAME defined
+        in a block that we aren't copying during tree_function_versioning,
+        just drop the clobber stmt.  */
+      if (id->blocks_to_copy && gimple_clobber_p (stmt))
+       {
+         tree lhs = gimple_assign_lhs (stmt);
+         if (TREE_CODE (lhs) == MEM_REF
+             && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
+           {
+             gimple def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (lhs, 0));
+             if (gimple_bb (def_stmt)
+                 && !bitmap_bit_p (id->blocks_to_copy,
+                                   gimple_bb (def_stmt)->index))
+               return gimple_build_nop ();
+           }
+       }
+
       if (gimple_debug_bind_p (stmt))
        {
          copy = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt),
@@ -5161,6 +5178,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
   id.src_node = old_version_node;
   id.dst_node = new_version_node;
   id.src_cfun = DECL_STRUCT_FUNCTION (old_decl);
+  id.blocks_to_copy = blocks_to_copy;
   if (id.src_node->ipa_transforms_to_apply.exists ())
     {
       vec<ipa_opt_pass> old_transforms_to_apply
index b65dee9350b63f0d6ce50da2ac7fb198ad6fb554..620ec9777685474a88433325aed61f93add8ae6c 100644 (file)
@@ -115,6 +115,10 @@ typedef struct copy_body_data
   /* Entry basic block to currently copied body.  */
   basic_block entry_bb;
 
+  /* For partial function versioning, bitmap of bbs to be copied,
+     otherwise NULL.  */
+  bitmap blocks_to_copy;
+
   /* Debug statements that need processing.  */
   vec<gimple> debug_stmts;