public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r10-8674] hppa: PR middle-end/87256: Improved hppa_rtx_costs avoids synth_mult madness.
@ 2020-08-26 6:24 Roger Sayle
0 siblings, 0 replies; only message in thread
From: Roger Sayle @ 2020-08-26 6:24 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:ed1e7a6a8ad6903ee952e82ac9ddac01efb286dd
commit r10-8674-ged1e7a6a8ad6903ee952e82ac9ddac01efb286dd
Author: Roger Sayle <roger@nextmovesoftware.com>
Date: Wed Aug 26 07:21:08 2020 +0100
hppa: PR middle-end/87256: Improved hppa_rtx_costs avoids synth_mult madness.
Backport from master:
2020-08-26 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR middle-end/87256
* config/pa/pa.c (hppa_rtx_costs_shadd_p): New helper function
to check for coefficients supported by shNadd and shladd,l.
(hppa_rtx_costs): Rewrite to avoid using estimates based upon
FACTOR and enable recursing deeper into RTL expressions.
* config/pa/pa.md (shd_internal): Fix define_expand to provide
gen_shd_internal.
Diff:
---
gcc/config/pa/pa.c | 172 +++++++++++++++++++++++++++++++++++++++++-----------
gcc/config/pa/pa.md | 6 +-
2 files changed, 141 insertions(+), 37 deletions(-)
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 711234e597a..55185aab650 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1492,6 +1492,33 @@ hppa_address_cost (rtx X, machine_mode mode ATTRIBUTE_UNUSED,
}
}
+/* Return true if X represents a (possibly non-canonical) shNadd pattern.
+ The machine mode of X is known to be SImode or DImode. */
+
+static bool
+hppa_rtx_costs_shadd_p (rtx x)
+{
+ if (GET_CODE (x) != PLUS
+ || !REG_P (XEXP (x, 1)))
+ return false;
+ rtx op0 = XEXP (x, 0);
+ if (GET_CODE (op0) == ASHIFT
+ && CONST_INT_P (XEXP (op0, 1))
+ && REG_P (XEXP (op0, 0)))
+ {
+ unsigned HOST_WIDE_INT x = UINTVAL (XEXP (op0, 1));
+ return x == 1 || x == 2 || x == 3;
+ }
+ if (GET_CODE (op0) == MULT
+ && CONST_INT_P (XEXP (op0, 1))
+ && REG_P (XEXP (op0, 0)))
+ {
+ unsigned HOST_WIDE_INT x = UINTVAL (XEXP (op0, 1));
+ return x == 2 || x == 4 || x == 8;
+ }
+ return false;
+}
+
/* Compute a (partial) cost for rtx X. Return true if the complete
cost has been computed, and false if subexpressions should be
scanned. In either case, *TOTAL contains the cost result. */
@@ -1499,15 +1526,16 @@ hppa_address_cost (rtx X, machine_mode mode ATTRIBUTE_UNUSED,
static bool
hppa_rtx_costs (rtx x, machine_mode mode, int outer_code,
int opno ATTRIBUTE_UNUSED,
- int *total, bool speed ATTRIBUTE_UNUSED)
+ int *total, bool speed)
{
- int factor;
int code = GET_CODE (x);
switch (code)
{
case CONST_INT:
- if (INTVAL (x) == 0)
+ if (outer_code == SET)
+ *total = COSTS_N_INSNS (1);
+ else if (INTVAL (x) == 0)
*total = 0;
else if (INT_14_BITS (x))
*total = 1;
@@ -1530,32 +1558,35 @@ hppa_rtx_costs (rtx x, machine_mode mode, int outer_code,
&& outer_code != SET)
*total = 0;
else
- *total = 8;
+ *total = 8;
return true;
case MULT:
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
*total = COSTS_N_INSNS (3);
- return true;
}
-
- /* A mode size N times larger than SImode needs O(N*N) more insns. */
- factor = GET_MODE_SIZE (mode) / 4;
- if (factor == 0)
- factor = 1;
-
- if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
- *total = factor * factor * COSTS_N_INSNS (8);
+ else if (mode == DImode)
+ {
+ if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
+ *total = COSTS_N_INSNS (32);
+ else
+ *total = COSTS_N_INSNS (80);
+ }
else
- *total = factor * factor * COSTS_N_INSNS (20);
- return true;
+ {
+ if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
+ *total = COSTS_N_INSNS (8);
+ else
+ *total = COSTS_N_INSNS (20);
+ }
+ return REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1));
case DIV:
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
*total = COSTS_N_INSNS (14);
- return true;
+ return false;
}
/* FALLTHRU */
@@ -1563,34 +1594,107 @@ hppa_rtx_costs (rtx x, machine_mode mode, int outer_code,
case MOD:
case UMOD:
/* A mode size N times larger than SImode needs O(N*N) more insns. */
- factor = GET_MODE_SIZE (mode) / 4;
- if (factor == 0)
- factor = 1;
-
- *total = factor * factor * COSTS_N_INSNS (60);
- return true;
+ if (mode == DImode)
+ *total = COSTS_N_INSNS (240);
+ else
+ *total = COSTS_N_INSNS (60);
+ return REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1));
case PLUS: /* this includes shNadd insns */
case MINUS:
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ *total = COSTS_N_INSNS (3);
+ else if (mode == DImode)
{
- *total = COSTS_N_INSNS (3);
- return true;
+ if (TARGET_64BIT)
+ {
+ *total = COSTS_N_INSNS (1);
+ /* Handle shladd,l instructions. */
+ if (hppa_rtx_costs_shadd_p (x))
+ return true;
+ }
+ else
+ *total = COSTS_N_INSNS (2);
}
-
- /* A size N times larger than UNITS_PER_WORD needs N times as
- many insns, taking N times as long. */
- factor = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
- if (factor == 0)
- factor = 1;
- *total = factor * COSTS_N_INSNS (1);
- return true;
+ else
+ {
+ *total = COSTS_N_INSNS (1);
+ /* Handle shNadd instructions. */
+ if (hppa_rtx_costs_shadd_p (x))
+ return true;
+ }
+ return REG_P (XEXP (x, 0))
+ && (REG_P (XEXP (x, 1))
+ || CONST_INT_P (XEXP (x, 1)));
case ASHIFT:
+ if (mode == DImode)
+ {
+ if (TARGET_64BIT)
+ *total = COSTS_N_INSNS (3);
+ else if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ else if (speed)
+ *total = COSTS_N_INSNS (13);
+ else
+ *total = COSTS_N_INSNS (18);
+ }
+ else if (TARGET_64BIT)
+ *total = COSTS_N_INSNS (4);
+ else
+ *total = COSTS_N_INSNS (2);
+ return REG_P (XEXP (x, 0))
+ && (REG_P (XEXP (x, 1))
+ || CONST_INT_P (XEXP (x, 1)));
+
case ASHIFTRT:
+ if (mode == DImode)
+ {
+ if (TARGET_64BIT)
+ *total = COSTS_N_INSNS (3);
+ else if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ else if (speed)
+ *total = COSTS_N_INSNS (14);
+ else
+ *total = COSTS_N_INSNS (19);
+ }
+ else if (TARGET_64BIT)
+ *total = COSTS_N_INSNS (4);
+ else
+ *total = COSTS_N_INSNS (2);
+ return REG_P (XEXP (x, 0))
+ && (REG_P (XEXP (x, 1))
+ || CONST_INT_P (XEXP (x, 1)));
+
case LSHIFTRT:
- *total = COSTS_N_INSNS (1);
- return true;
+ if (mode == DImode)
+ {
+ if (TARGET_64BIT)
+ *total = COSTS_N_INSNS (2);
+ else if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ else if (speed)
+ *total = COSTS_N_INSNS (12);
+ else
+ *total = COSTS_N_INSNS (15);
+ }
+ else if (TARGET_64BIT)
+ *total = COSTS_N_INSNS (3);
+ else
+ *total = COSTS_N_INSNS (2);
+ return REG_P (XEXP (x, 0))
+ && (REG_P (XEXP (x, 1))
+ || CONST_INT_P (XEXP (x, 1)));
default:
return false;
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index e7b76355527..713ff175445 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -6423,15 +6423,15 @@
{
if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
{
- unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
+ unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
if (shift >= 1 && shift <= 31)
{
rtx dst = operands[0];
rtx src = force_reg (DImode, operands[1]);
emit_insn (gen_shd_internal (gen_highpart (SImode, dst),
- gen_highpart (SImode, src),
- GEN_INT (32-shift),
gen_lowpart (SImode, src),
+ GEN_INT (32-shift),
+ gen_highpart (SImode, src),
GEN_INT (shift)));
emit_insn (gen_ashlsi3 (gen_lowpart (SImode, dst),
gen_lowpart (SImode, src),
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-08-26 6:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-26 6:24 [gcc r10-8674] hppa: PR middle-end/87256: Improved hppa_rtx_costs avoids synth_mult madness Roger Sayle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).