diff mbox

Prevent infinite recursion between simplification and CSE in FRE

Message ID alpine.DEB.2.02.1706170909380.6123@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse June 17, 2017, 7:35 a.m. UTC
Hello,

see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80887#c10 for the 
context. FRE can go into an infinite recursion with some match.pd 
simplifications (that have been temporarily reverted).

Limiting the depth of recursive calls is not a great solution, but it is 
simple and I don't have a good idea for an alternate solution that does 
not disable a lot of desirable optimizations.

There are many ways to write the limiter, I went with

   depth_limiter d;
   if (d > 100) return false;

but I could also have written the class so the use would look like

   depth_limiter d(100);
   if (!d) return false;

for instance.

100 was picked arbitrarily, I don't think it is worth having a param for 
it, but we could certainly use a different value.

Bootstrap and testsuite on powerpc64le-unknown-linux-gnu.

2017-06-19  Marc Glisse  <marc.glisse@inria.fr>

 	* gimple-match-head.c (depth_limiter): New class.
 	* genmatch.c (decision_tree::gen): Use it.
diff mbox

Patch

Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c	(revision 249277)
+++ gcc/genmatch.c	(working copy)
@@ -3684,21 +3684,25 @@  decision_tree::gen (FILE *f, bool gimple
 		 "                 gimple_seq *seq, tree (*valueize)(tree),\n"
 		 "                 code_helper code, tree type");
       else
 	fprintf (f, "\ntree\n"
 		 "generic_simplify (location_t loc, enum tree_code code, "
 		 "tree type ATTRIBUTE_UNUSED");
       for (unsigned i = 0; i < n; ++i)
 	fprintf (f, ", tree op%d", i);
       fprintf (f, ")\n");
       fprintf (f, "{\n");
-
+      if (gimple)
+	{
+	  fprintf (f, "  depth_limiter d;\n");
+	  fprintf (f, "  if (d > 100) return false;\n");
+	}
       if (gimple)
 	fprintf (f, "  switch (code.get_rep())\n"
 		 "    {\n");
       else
 	fprintf (f, "  switch (code)\n"
 		 "    {\n");
       for (unsigned i = 0; i < root->kids.length (); i++)
 	{
 	  dt_operand *dop = static_cast<dt_operand *>(root->kids[i]);
 	  expr *e = static_cast<expr *>(dop->op);
Index: gcc/gimple-match-head.c
===================================================================
--- gcc/gimple-match-head.c	(revision 249277)
+++ gcc/gimple-match-head.c	(working copy)
@@ -808,10 +808,22 @@  single_use (tree t)
 }
 
 /* Return true if math operations should be canonicalized,
    e.g. sqrt(sqrt(x)) -> pow(x, 0.25).  */
 
 static inline bool
 canonicalize_math_p ()
 {
   return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
 }
+
+/* Simple way to prevent infinite recursion in simplification.  */
+namespace {
+  struct depth_limiter
+  {
+    static int depth;
+    operator int () const { return depth; }
+    depth_limiter () { ++depth; }
+    ~depth_limiter () { --depth; }
+  };
+  int depth_limiter::depth = 0;
+}