This patch adds CCMP selection based on rtx costs. This is based on Jiong's already approved patch https://gcc.gnu.org/ml/gcc-patches/2015-09/msg01434.html with some minor refactoring and the tests updated.
OK for commit? ChangeLog: 2015-11-13 Jiong Wang <jiong.w...@arm.com> gcc/ * ccmp.c (expand_ccmp_expr_1): Cost the instruction sequences generated from different expand order. gcc/testsuite/ * gcc.target/aarch64/ccmp_1.c: Update test. --- gcc/ccmp.c | 47 +++++++++++++++++++++++++++---- gcc/testsuite/gcc.target/aarch64/ccmp_1.c | 15 ++++++++-- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/gcc/ccmp.c b/gcc/ccmp.c index cbdbd6d..95a41a6 100644 --- a/gcc/ccmp.c +++ b/gcc/ccmp.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-outof-ssa.h" #include "cfgexpand.h" #include "ccmp.h" +#include "predict.h" /* The following functions expand conditional compare (CCMP) instructions. Here is a short description about the over all algorithm: @@ -159,6 +160,8 @@ expand_ccmp_next (gimple *g, enum tree_code code, rtx prev, static rtx expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq) { + rtx prep_seq_1, gen_seq_1; + rtx prep_seq_2, gen_seq_2; tree exp = gimple_assign_rhs_to_tree (g); enum tree_code code = TREE_CODE (exp); gimple *gs0 = get_gimple_for_ssa_name (TREE_OPERAND (exp, 0)); @@ -174,19 +177,53 @@ expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq) { if (TREE_CODE_CLASS (code1) == tcc_comparison) { - int unsignedp0; - enum rtx_code rcode0; + int unsignedp0, unsignedp1; + enum rtx_code rcode0, rcode1; + int speed_p = optimize_insn_for_speed_p (); + rtx tmp2, ret, ret2; + unsigned cost1 = MAX_COST; + unsigned cost2 = MAX_COST; unsignedp0 = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs0))); + unsignedp1 = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs1))); rcode0 = get_rtx_code (code0, unsignedp0); + rcode1 = get_rtx_code (code1, unsignedp1); - tmp = targetm.gen_ccmp_first (prep_seq, gen_seq, rcode0, + tmp = targetm.gen_ccmp_first (&prep_seq_1, &gen_seq_1, rcode0, gimple_assign_rhs1 (gs0), gimple_assign_rhs2 (gs0)); - if (!tmp) + + 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; - return expand_ccmp_next (gs1, code, tmp, prep_seq, gen_seq); + if (tmp != NULL) + { + ret = expand_ccmp_next (gs1, code, tmp, &prep_seq_1, &gen_seq_1); + cost1 = seq_cost (safe_as_a <rtx_insn *> (prep_seq_1), speed_p); + cost1 += seq_cost (safe_as_a <rtx_insn *> (gen_seq_1), speed_p); + } + if (tmp2 != NULL) + { + ret2 = expand_ccmp_next (gs0, code, tmp2, &prep_seq_2, + &gen_seq_2); + cost2 = seq_cost (safe_as_a <rtx_insn *> (prep_seq_2), speed_p); + cost2 += seq_cost (safe_as_a <rtx_insn *> (gen_seq_2), speed_p); + } + + if (cost2 < cost1) + { + *prep_seq = prep_seq_2; + *gen_seq = gen_seq_2; + return ret2; + } + + *prep_seq = prep_seq_1; + *gen_seq = gen_seq_1; + return ret; } else { diff --git a/gcc/testsuite/gcc.target/aarch64/ccmp_1.c b/gcc/testsuite/gcc.target/aarch64/ccmp_1.c index ef077e0..7c39b61 100644 --- a/gcc/testsuite/gcc.target/aarch64/ccmp_1.c +++ b/gcc/testsuite/gcc.target/aarch64/ccmp_1.c @@ -80,5 +80,16 @@ f13 (int a, int b) return a == 3 || a == 0; } -/* { dg-final { scan-assembler "fccmp\t" } } */ -/* { dg-final { scan-assembler "fccmpe\t" } } */ +/* { dg-final { scan-assembler "cmp\t(.)+32" } } */ +/* { dg-final { scan-assembler "cmp\t(.)+33" } } */ +/* { dg-final { scan-assembler "cmp\t(.)+34" } } */ +/* { dg-final { scan-assembler "cmp\t(.)+35" } } */ + +/* { dg-final { scan-assembler-times "\tcmp\tw\[0-9\]+, 0" 4 } } */ +/* { dg-final { scan-assembler-times "fcmpe\t(.)+0\\.0" 2 } } */ +/* { dg-final { scan-assembler-times "fcmp\t(.)+0\\.0" 2 } } */ + +/* { dg-final { scan-assembler "adds\t" } } */ +/* { dg-final { scan-assembler-times "\tccmp\t" 11 } } */ +/* { dg-final { scan-assembler-times "fccmp\t.*0\\.0" 1 } } */ +/* { dg-final { scan-assembler-times "fccmpe\t.*0\\.0" 1 } } */ -- 1.9.1