From 08fd6cf566033c9ff7ebc402aa3fa41a05b40215 Mon Sep 17 00:00:00 2001 From: wilco Date: Thu, 4 Feb 2016 18:23:35 +0000 Subject: [PATCH] This patch fixes an exponential issue in ccmp.c. When deciding which ccmp expansion to use, the tree nodes gs0 and gs1 are fully expanded twice. If they contain more CCMP opportunities, their subtrees are also expanded twice. When the trees are complex the expansion takes exponential time and memory. As a workaround in GCC6 compute the cost of the first expansion early, and only try the alternative expansion if the cost is low enough. This rarely affects real code, eg. SPECINT2006 has identical codesize. 2016-02-04 Wilco Dijkstra gcc/ PR target/69619 * ccmp.c (expand_ccmp_expr_1): Avoid evaluating gs0/gs1 twice when complex. gcc/testsuite/ PR target/69619 * gcc.dg/pr69619.c: Add new test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233145 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/ccmp.c | 22 ++++++++++++++-------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr69619.c | 20 ++++++++++++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr69619.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c76070f8af1f..7c2dae852872 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-02-04 Wilco Dijkstra + + PR target/69619 + * ccmp.c (expand_ccmp_expr_1): Avoid evaluating gs0/gs1 + twice when complex. + 2016-02-04 Mike Frysinger * doc/invoke.texi: Delete -mno-fma4. diff --git a/gcc/ccmp.c b/gcc/ccmp.c index 9f1ce295554d..6f95acec95b5 100644 --- a/gcc/ccmp.c +++ b/gcc/ccmp.c @@ -170,7 +170,7 @@ expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq) int unsignedp0, unsignedp1; rtx_code rcode0, rcode1; int speed_p = optimize_insn_for_speed_p (); - rtx tmp2, ret = NULL_RTX, ret2 = NULL_RTX; + rtx tmp2 = NULL_RTX, ret = NULL_RTX, ret2 = NULL_RTX; unsigned cost1 = MAX_COST; unsigned cost2 = MAX_COST; @@ -183,19 +183,25 @@ expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq) gimple_assign_rhs1 (gs0), gimple_assign_rhs2 (gs0)); - tmp2 = targetm.gen_ccmp_first (&prep_seq_2, &gen_seq_2, rcode1, - gimple_assign_rhs1 (gs1), - gimple_assign_rhs2 (gs1)); - - if (!tmp && !tmp2) - return NULL_RTX; - if (tmp != NULL) { ret = expand_ccmp_next (gs1, code, tmp, &prep_seq_1, &gen_seq_1); cost1 = seq_cost (safe_as_a (prep_seq_1), speed_p); cost1 += seq_cost (safe_as_a (gen_seq_1), speed_p); } + + /* FIXME: Temporary workaround for PR69619. + Avoid exponential compile time due to expanding gs0 and gs1 twice. + If gs0 and gs1 are complex, the cost will be high, so avoid + reevaluation if above an arbitrary threshold. */ + if (tmp == NULL || cost1 < COSTS_N_INSNS (25)) + tmp2 = targetm.gen_ccmp_first (&prep_seq_2, &gen_seq_2, rcode1, + gimple_assign_rhs1 (gs1), + gimple_assign_rhs2 (gs1)); + + if (!tmp && !tmp2) + return NULL_RTX; + if (tmp2 != NULL) { ret2 = expand_ccmp_next (gs0, code, tmp2, &prep_seq_2, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 66115f01555c..f2f73b609fd4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-04 Wilco Dijkstra + + PR target/69619 + * gcc.dg/pr69619.c: Add new test. + 2016-02-04 Richard Sandiford PR rtl-optimization/69577 diff --git a/gcc/testsuite/gcc.dg/pr69619.c b/gcc/testsuite/gcc.dg/pr69619.c new file mode 100644 index 000000000000..a200bdf310fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69619.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a, b, c, d; +int e[100]; +void +fn1 () +{ + int *f = &d; + c = 6; + for (; c; c--) + { + b = 0; + for (; b <= 5; b++) + { + short g = e[(b + 2) * 9 + c]; + *f = *f == a && e[(b + 2) * 9 + c]; + } + } +} -- 2.47.3