This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][RFT] Reduce gimple-match.c compile-time(?)


On Fri, 24 Jul 2015, Richard Biener wrote:

> 
> The following patch implements the simplest approach of splitting
> the huge functions in gimple-match.c (not yet generic-match.c).
...
> Can people who reported huge compile-times test this patch
> and report back?

Positive feedback on IRC and thus I am applying the following
simplified variant.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Richard.

2015-07-27  Richard Biener  <rguenther@suse.de>

	* genmatch.c (decision_tree::gen_gimple): Split out large
	subtrees into separate functions.
	(decision_tree::gen_generic): Likewise.

Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c	(revision 226240)
+++ gcc/genmatch.c	(working copy)
@@ -2951,6 +2964,32 @@ decision_tree::gen_gimple (FILE *f)
 
   for (unsigned n = 1; n <= 3; ++n)
     {
+      /* First generate split-out functions.  */
+      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);
+	  if (e->ops.length () != n)
+	    continue;
+
+	  fprintf (f, "\nstatic bool\n"
+		   "gimple_simplify_%s (code_helper *res_code, tree *res_ops,\n"
+		   "                 gimple_seq *seq, tree (*valueize)(tree) "
+		   "ATTRIBUTE_UNUSED,\n"
+		   "                 code_helper ARG_UNUSED (code), tree "
+		   "ARG_UNUSED (type)\n",
+		   e->operation->id);
+	  for (unsigned i = 0; i < n; ++i)
+	    fprintf (f, ", tree op%d", i);
+	  fprintf (f, ")\n");
+	  fprintf (f, "{\n");
+	  dop->gen_kids (f, 2, true);
+	  fprintf (f, "  return false;\n");
+	  fprintf (f, "}\n");
+	}
+
+      /* Then generate the main entry with the outermost switch and
+         tail-calls to the split-out functions.  */
       fprintf (f, "\nstatic bool\n"
 	       "gimple_simplify (code_helper *res_code, tree *res_ops,\n"
 	       "                 gimple_seq *seq, tree (*valueize)(tree),\n"
@@ -2976,10 +3015,11 @@ decision_tree::gen_gimple (FILE *f)
 	    fprintf (f, "    case %s%s:\n",
 		     is_a <fn_id *> (e->operation) ? "-" : "",
 		     e->operation->id);
-	  fprintf (f,   "      {\n");
-	  dop->gen_kids (f, 8, true);
-	  fprintf (f,   "        break;\n");
-	  fprintf (f,   "      }\n");
+	  fprintf (f, "      return gimple_simplify_%s (res_code, res_ops, "
+		   "seq, valueize, code, type", e->operation->id);
+	  for (unsigned i = 0; i < n; ++i)
+	    fprintf (f, ", op%d", i);
+	  fprintf (f, ");\n");
 	}
       fprintf (f,       "    default:;\n"
 	                "    }\n");
@@ -3003,6 +3043,34 @@ decision_tree::gen_generic (FILE *f)
 
   for (unsigned n = 1; n <= 3; ++n)
     {
+      /* First generate split-out functions.  */
+      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);
+	  if (e->ops.length () != n
+	      /* Builtin simplifications are somewhat premature on
+	         GENERIC.  The following drops patterns with outermost
+		 calls.  It's easy to emit overloads for function code
+		 though if necessary.  */
+	      || e->operation->kind != id_base::CODE)
+	    continue;
+
+	  fprintf (f, "\nstatic tree\n"
+		   "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
+		   "tree_code ARG_UNUSED (code), tree ARG_UNUSED (type)",
+		   e->operation->id);
+	  for (unsigned i = 0; i < n; ++i)
+	    fprintf (f, ", tree op%d", i);
+	  fprintf (f, ")\n");
+	  fprintf (f, "{\n");
+	  dop->gen_kids (f, 2, false);
+	  fprintf (f, "  return NULL_TREE;\n");
+	  fprintf (f, "}\n");
+	}
+
+      /* Then generate the main entry with the outermost switch and
+         tail-calls to the split-out functions.  */
       fprintf (f, "\ntree\n"
 	       "generic_simplify (location_t loc, enum tree_code code, "
 	       "tree type ATTRIBUTE_UNUSED");
@@ -3030,10 +3098,11 @@ decision_tree::gen_generic (FILE *f)
 	    fprintf (f, "    CASE_CONVERT:\n");
 	  else
 	    fprintf (f, "    case %s:\n", e->operation->id);
-	  fprintf (f,   "      {\n");
-	  dop->gen_kids (f, 8, false);
-	  fprintf (f,   "        break;\n"
-		        "      }\n");
+	  fprintf (f, "      return generic_simplify_%s (loc, code, type",
+		   e->operation->id);
+	  for (unsigned i = 0; i < n; ++i)
+	    fprintf (f, ", op%d", i);
+	  fprintf (f, ");\n");
 	}
       fprintf (f, "    default:;\n"
 	          "    }\n");


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]