]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorRichard Biener <rguenther@suse.de>
Fri, 12 Oct 2018 13:44:35 +0000 (13:44 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 12 Oct 2018 13:44:35 +0000 (13:44 +0000)
2018-10-12  Richard Biener  <rguenther@suse.de>

PR c++/54278
Backport from mainline
2017-03-23  Richard Biener  <rguenther@suse.de>

PR tree-optimization/80032
* gimplify.c (gimple_push_cleanup): Forced unconditional
cleanups still have to go to the conditional_cleanups
sequence.

2017-03-21  Richard Biener  <rguenther@suse.de>

PR tree-optimization/80032
* gimplify.c (gimple_push_cleanup): Add force_uncond parameter,
if set force the cleanup to happen unconditionally.
(gimplify_target_expr): Push inserted clobbers with force_uncond
to avoid them being removed by control-dependent DCE.

* g++.dg/opt/pr80032.C: New testcase.

From-SVN: r265101

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr80032.C [new file with mode: 0644]

index 8fa30fdbbd7ef8c1b0e8fbf27e1fbd52e4dfa249..911c49b31eb80ec26b8855650f535cc192de8282 100644 (file)
@@ -1,3 +1,22 @@
+2018-10-12  Richard Biener  <rguenther@suse.de>
+
+       PR c++/54278
+       Backport from mainline
+       2017-03-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/80032
+       * gimplify.c (gimple_push_cleanup): Forced unconditional
+       cleanups still have to go to the conditional_cleanups
+       sequence.
+
+       2017-03-21  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/80032
+       * gimplify.c (gimple_push_cleanup): Add force_uncond parameter,
+       if set force the cleanup to happen unconditionally.
+       (gimplify_target_expr): Push inserted clobbers with force_uncond
+       to avoid them being removed by control-dependent DCE.
+
 2018-10-12  H.J. Lu  <hongjiu.lu@intel.com>
 
        Backport from mainline
index e55f5b4216ddddcfcf723b4bdc3298e8ee66d338..e59fa5a68075121cb8cab8c443ee74c53f82be01 100644 (file)
@@ -5534,10 +5534,13 @@ gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
 
 /* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
    is the cleanup action required.  EH_ONLY is true if the cleanup should
-   only be executed if an exception is thrown, not on normal exit.  */
+   only be executed if an exception is thrown, not on normal exit.
+   If FORCE_UNCOND is true perform the cleanup unconditionally;  this is
+   only valid for clobbers.  */
 
 static void
-gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
+gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
+                    bool force_uncond = false)
 {
   gimple *wce;
   gimple_seq cleanup_stmts = NULL;
@@ -5569,22 +5572,31 @@ gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
           }
           val
       */
-      tree flag = create_tmp_var (boolean_type_node, "cleanup");
-      gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
-      gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
-
-      cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
-      gimplify_stmt (&cleanup, &cleanup_stmts);
-      wce = gimple_build_wce (cleanup_stmts);
-
-      gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
-      gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
-      gimplify_seq_add_stmt (pre_p, ftrue);
-
-      /* Because of this manipulation, and the EH edges that jump
-        threading cannot redirect, the temporary (VAR) will appear
-        to be used uninitialized.  Don't warn.  */
-      TREE_NO_WARNING (var) = 1;
+      if (force_uncond)
+       {
+         gimplify_stmt (&cleanup, &cleanup_stmts);
+         wce = gimple_build_wce (cleanup_stmts);
+         gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
+       }
+      else
+       {
+         tree flag = create_tmp_var (boolean_type_node, "cleanup");
+         gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
+         gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
+
+         cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
+         gimplify_stmt (&cleanup, &cleanup_stmts);
+         wce = gimple_build_wce (cleanup_stmts);
+
+         gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
+         gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
+         gimplify_seq_add_stmt (pre_p, ftrue);
+
+         /* Because of this manipulation, and the EH edges that jump
+            threading cannot redirect, the temporary (VAR) will appear
+            to be used uninitialized.  Don't warn.  */
+         TREE_NO_WARNING (var) = 1;
+       }
     }
   else
     {
@@ -5661,11 +5673,7 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
                                            NULL);
          TREE_THIS_VOLATILE (clobber) = true;
          clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
-         if (cleanup)
-           cleanup = build2 (COMPOUND_EXPR, void_type_node, cleanup,
-                             clobber);
-         else
-           cleanup = clobber;
+         gimple_push_cleanup (temp, clobber, false, pre_p, true);
        }
 
       if (cleanup)
index 726699b6ecb748435f5b769d8f02962e2386229a..f933ad258115deb153b0a7e1ec2bf5c8f49df8c9 100644 (file)
@@ -1,3 +1,12 @@
+2018-10-12  Richard Biener  <rguenther@suse.de>
+
+       PR c++/54278
+       Backport from mainline
+       2017-03-21  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/80032
+       * g++.dg/opt/pr80032.C: New testcase.
+
 2018-09-07  Janus Weil  <janus@gcc.gnu.org>
 
        Backported from trunk
diff --git a/gcc/testsuite/g++.dg/opt/pr80032.C b/gcc/testsuite/g++.dg/opt/pr80032.C
new file mode 100644 (file)
index 0000000..8475fdb
--- /dev/null
@@ -0,0 +1,121 @@
+// PR tree-optimization/80032
+/* { dg-do compile } */
+/* { dg-require-effective-target c++11 } */
+/* { dg-options "-O2" } */
+/* If DCE removes too many CLOBBERs then stack usage goes through the
+   roof as stack slots can no longer be shared.  */
+/* { dg-additional-options "-Wstack-usage=200" { target x86_64-*-* i?86-*-* } } */
+
+typedef unsigned a;
+namespace test {
+    enum b { c };
+    class ADataContainer;
+    class BitMask;
+    namespace api {
+       enum DataStore { candidate };
+    }
+    using d = api::DataStore;
+    namespace db {
+       class e;
+       class f;
+       class g;
+       class ManagedObjectConst {
+       public:
+           ManagedObjectConst(const ManagedObjectConst &);
+           bool isFieldDefault(a, d) const;
+           ADataContainer &getFieldDefault(a, d) const;
+           g *h;
+           e *i;
+           f *j;
+       };
+       struct FieldInfo {
+           FieldInfo(ManagedObjectConst, a, d);
+           ManagedObjectConst k;
+       };
+       b compare(const FieldInfo &, const ADataContainer &);
+       class ManagedObject : public ManagedObjectConst {};
+    }
+    using namespace db;
+    void FN(ManagedObject &k, const BitMask &) {
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+       if (!k.isFieldDefault(8, d::candidate) &&
+           !compare(FieldInfo(k, 11, d::candidate),
+                    k.getFieldDefault(11, d::candidate)) == c)
+         return;
+    }
+}