This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][RFT] Reduce gimple-match.c compile-time(?)
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 27 Jul 2015 12:55:12 +0200 (CEST)
- Subject: Re: [PATCH][RFT] Reduce gimple-match.c compile-time(?)
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LSU dot 2 dot 11 dot 1507241440140 dot 19642 at zhemvz dot fhfr dot qr>
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");