aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorXiao Zeng <zengxiao@eswincomputing.com>2023-07-31 12:26:51 -0600
committerJeff Law <jlaw@ventanamicro.com>2023-08-01 23:08:59 -0600
commite15d0b6680d10d7666195e9db65581364ad5e5df (patch)
treec7e1d3e51e90f5483c959f407c24ed04f891aded /gcc
parenteb0a9102a93e4a5ae8f0db707812e140100617d4 (diff)
downloadgcc-e15d0b6680d10d7666195e9db65581364ad5e5df.zip
gcc-e15d0b6680d10d7666195e9db65581364ad5e5df.tar.gz
gcc-e15d0b6680d10d7666195e9db65581364ad5e5df.tar.bz2
[PATCH 3/5] [RISC-V] RISC-V Conditional Move costing [was:Generate Zicond instruction for select pattern with condition eq or neq to 0]
This provides some basic costing to conditional moves. The underlying primitive of an IF-THEN-ELSE which turns into czero is a single insn (COSTS_N_INSNS (1)). But these insns were still consistently showing up with the wrong cost (8 instead of 4). This was chased down to computing the cost of the destination and the cost of the source independently, then summing them. That seems horribly wrong for register destinations. So this patch special cases an INSN that is just a SET of a register destination so that the cost comes from the SET_SRC. Long term the whole costing model needs a review. gcc/ * config/riscv/riscv.cc (riscv_rtx_costs, case IF_THEN_ELSE): Add Zicond costing. (case SET): For INSNs that just set a REG, take the cost from the SET_SRC. Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index b6a57d0..8c47450 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2504,6 +2504,20 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (1);
return true;
}
+ else if (TARGET_ZICOND
+ && outer_code == SET
+ && ((GET_CODE (XEXP (x, 1)) == REG
+ && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1))))
+ || (GET_CODE (XEXP (x, 2)) == REG
+ && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 2))))
+ || (GET_CODE (XEXP (x, 1)) == REG
+ && rtx_equal_p (XEXP (x, 1), XEXP (XEXP (x, 0), 0)))
+ || (GET_CODE (XEXP (x, 1)) == REG
+ && rtx_equal_p (XEXP (x, 2), XEXP (XEXP (x, 0), 0)))))
+ {
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
else if (LABEL_REF_P (XEXP (x, 1)) && XEXP (x, 2) == pc_rtx)
{
if (equality_operator (XEXP (x, 0), mode)
@@ -2881,6 +2895,16 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
}
return false;
+ case SET:
+ /* A simple SET with a register destination takes its cost solely from
+ the SET_SRC operand. */
+ if (outer_code == INSN && REG_P (SET_DEST (x)))
+ {
+ *total = riscv_rtx_costs (SET_SRC (x), mode, SET, opno, total, speed);
+ return true;
+ }
+ return false;
+
default:
return false;
}