diff options
author | jiwang <jiwang@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-19 14:14:56 +0000 |
---|---|---|
committer | jiwang <jiwang@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-19 14:14:56 +0000 |
commit | 07bd240ed93406c063fd6f7a42e18a533f7ae556 (patch) | |
tree | 8b9c7e2731d1acece79c506065da6b6bbed8eed0 /gcc/ccmp.c | |
parent | be1c970c1cd43cf9327c4f9352afc168e55fb560 (diff) | |
download | gcc-07bd240ed93406c063fd6f7a42e18a533f7ae556.tar.gz |
[PATCH 4/4] Add CCMP selection based on rtx costs
2015-01-19 Wilco Dijkstra <wdijkstr@arm.com>
Jiong Wang <jiong.wang@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: Add new tests.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232565 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ccmp.c')
-rw-r--r-- | gcc/ccmp.c | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/gcc/ccmp.c b/gcc/ccmp.c index a393d3546f3..9e49d1e4e4a 100644 --- a/gcc/ccmp.c +++ b/gcc/ccmp.c @@ -35,6 +35,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: @@ -72,7 +73,7 @@ ccmp_candidate_p (gimple *g) tree rhs = gimple_assign_rhs_to_tree (g); tree lhs, op0, op1; gimple *gs0, *gs1; - enum tree_code tcode, tcode0, tcode1; + tree_code tcode, tcode0, tcode1; tcode = TREE_CODE (rhs); if (tcode != BIT_AND_EXPR && tcode != BIT_IOR_EXPR) @@ -119,10 +120,10 @@ ccmp_candidate_p (gimple *g) PREP_SEQ returns all insns to prepare opearands for compare. GEN_SEQ returns all compare insns. */ static rtx -expand_ccmp_next (gimple *g, enum tree_code code, rtx prev, +expand_ccmp_next (gimple *g, tree_code code, rtx prev, rtx *prep_seq, rtx *gen_seq) { - enum rtx_code rcode; + rtx_code rcode; int unsignedp = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g))); gcc_assert (code == BIT_AND_EXPR || code == BIT_IOR_EXPR); @@ -149,13 +150,15 @@ 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); + tree_code code = TREE_CODE (exp); gimple *gs0 = get_gimple_for_ssa_name (TREE_OPERAND (exp, 0)); gimple *gs1 = get_gimple_for_ssa_name (TREE_OPERAND (exp, 1)); rtx tmp; - enum tree_code code0 = gimple_assign_rhs_code (gs0); - enum tree_code code1 = gimple_assign_rhs_code (gs1); + tree_code code0 = gimple_assign_rhs_code (gs0); + tree_code code1 = gimple_assign_rhs_code (gs1); gcc_assert (code == BIT_AND_EXPR || code == BIT_IOR_EXPR); gcc_assert (gs0 && gs1 && is_gimple_assign (gs0) && is_gimple_assign (gs1)); @@ -164,19 +167,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; + 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 { @@ -230,8 +267,8 @@ expand_ccmp_expr (gimple *g) if (tmp) { - enum insn_code icode; - enum machine_mode cc_mode = CCmode; + insn_code icode; + machine_mode cc_mode = CCmode; tree lhs = gimple_assign_lhs (g); rtx_code cmp_code = GET_CODE (tmp); @@ -241,7 +278,7 @@ expand_ccmp_expr (gimple *g) icode = optab_handler (cstore_optab, cc_mode); if (icode != CODE_FOR_nothing) { - enum machine_mode mode = TYPE_MODE (TREE_TYPE (lhs)); + machine_mode mode = TYPE_MODE (TREE_TYPE (lhs)); rtx target = gen_reg_rtx (mode); emit_insn (prep_seq); |