On 10/12/23 17:04, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
My recent patch introducing cp_fold_immediate_r caused exponential
compile time with nested COND_EXPRs.  The problem is that the COND_EXPR
case recursively walks the arms of a COND_EXPR, but after processing
both arms it doesn't end the walk; it proceeds to walk the
sub-expressions of the outermost COND_EXPR, triggering again walking
the arms of the nested COND_EXPR, and so on.  This patch brings the
compile time down to about 0m0.033s.

I've added some debug prints to make sure that the rest of cp_fold_r
is still performed as before.

         PR c++/111660

gcc/cp/ChangeLog:

         * cp-gimplify.cc (cp_fold_immediate_r) <case COND_EXPR>: Return
         integer_zero_node instead of break;.
         (cp_fold_immediate): Return true if cp_fold_immediate_r returned
         error_mark_node.

gcc/testsuite/ChangeLog:

         * g++.dg/cpp0x/hog1.C: New test.
---
  gcc/cp/cp-gimplify.cc             |  9 ++--
  gcc/testsuite/g++.dg/cpp0x/hog1.C | 77 +++++++++++++++++++++++++++++++
  2 files changed, 82 insertions(+), 4 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/hog1.C

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index bdf6e5f98ff..ca622ca169a 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1063,16 +1063,16 @@ cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, 
void *data_)
        break;
        if (TREE_OPERAND (stmt, 1)
          && cp_walk_tree (&TREE_OPERAND (stmt, 1), cp_fold_immediate_r, data,
-                          nullptr))
+                          nullptr) == error_mark_node)
        return error_mark_node;
        if (TREE_OPERAND (stmt, 2)
          && cp_walk_tree (&TREE_OPERAND (stmt, 2), cp_fold_immediate_r, data,
-                          nullptr))
+                          nullptr) == error_mark_node)
        return error_mark_node;
        /* We're done here.  Don't clear *walk_subtrees here though: we're 
called
         from cp_fold_r and we must let it recurse on the expression with
         cp_fold.  */
-      break;
+      return integer_zero_node;

I'm concerned this will end up missing something like

1 ? 1 : ((1 ? 1 : 1), immediate())

as the integer_zero_node from the inner ?: will prevent walk_tree from looking any farther.

Maybe we want to handle COND_EXPR in cp_fold_r instead of here?

Jason

Reply via email to