public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 3/4] xtensa: Improve instruction cost estimation and suggestion
@ 2022-06-10  4:19 Takayuki 'January June' Suwa
  2022-06-11 23:13 ` Max Filippov
  0 siblings, 1 reply; 2+ messages in thread
From: Takayuki 'January June' Suwa @ 2022-06-10  4:19 UTC (permalink / raw)
  To: GCC Patches

This patch implements a new target-specific relative RTL insn cost function
because of suboptimal cost estimation by default, and fixes several "length"
insn attributes (related to the cost estimation).

And also introduces a new machine-dependent option "-mextra-l32r-costs="
that tells implementation-specific InstRAM/ROM access penalty for L32R
instruction to the compiler (in clock-cycle units, 0 by default).

gcc/ChangeLog:

	* config/xtensa/xtensa.cc (xtensa_rtx_costs): Correct wrong case
	for ABS and NEG, add missing case for BSWAP and CLRSB, and
	double the costs for integer divisions using libfuncs if
	optimizing for speed, in order to take advantage of fast constant
	division by multiplication.
	(TARGET_INSN_COST): New macro definition.
	(xtensa_is_insn_L32R_p, xtensa_insn_cost): New functions for
	calculating relative costs of a RTL insns, for both of speed and
	size.
	* config/xtensa/xtensa.md (return, nop, trap): Correct values of
	the attribute "length" that depends on TARGET_DENSITY.
	(define_asm_attributes, blockage, frame_blockage): Add missing
	attributes.
	* config/xtensa/xtensa.opt (-mextra-l32r-costs=): New machine-
	dependent option, however, preparatory work for now.
---
  gcc/config/xtensa/xtensa.cc  | 116 ++++++++++++++++++++++++++++++++---
  gcc/config/xtensa/xtensa.md  |  29 ++++++---
  gcc/config/xtensa/xtensa.opt |   4 ++
  3 files changed, 134 insertions(+), 15 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 616ced3ed38..1769e43c7b5 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
  #include "dumpfile.h"
  #include "hw-doloop.h"
  #include "rtl-iter.h"
+#include "insn-attr.h"

  /* This file should be included last.  */
  #include "target-def.h"
@@ -134,6 +135,7 @@ static unsigned int 
xtensa_multibss_section_type_flags (tree, const char *,
  static section *xtensa_select_rtx_section (machine_mode, rtx,
  					   unsigned HOST_WIDE_INT);
  static bool xtensa_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+static int xtensa_insn_cost (rtx_insn *, bool);
  static int xtensa_register_move_cost (machine_mode, reg_class_t,
  				      reg_class_t);
  static int xtensa_memory_move_cost (machine_mode, reg_class_t, bool);
@@ -212,6 +214,8 @@ static rtx xtensa_delegitimize_address (rtx);
  #define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost
  #undef TARGET_RTX_COSTS
  #define TARGET_RTX_COSTS xtensa_rtx_costs
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST xtensa_insn_cost
  #undef TARGET_ADDRESS_COST
  #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0

@@ -3933,7 +3937,7 @@ xtensa_memory_move_cost (machine_mode mode 
ATTRIBUTE_UNUSED,
  static bool
  xtensa_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 code = GET_CODE (x);

@@ -4021,9 +4025,14 @@ xtensa_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
        return true;

      case CLZ:
+    case CLRSB:
        *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50);
        return true;

+    case BSWAP:
+      *total = COSTS_N_INSNS (mode == HImode ? 3 : 5);
+      return true;
+
      case NOT:
        *total = COSTS_N_INSNS (mode == DImode ? 3 : 2);
        return true;
@@ -4047,13 +4056,16 @@ xtensa_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
        return true;

      case ABS:
+    case NEG:
        {
  	if (mode == SFmode)
  	  *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
  	else if (mode == DFmode)
  	  *total = COSTS_N_INSNS (50);
-	else
+	else if (mode == DImode)
  	  *total = COSTS_N_INSNS (4);
+	else
+	  *total = COSTS_N_INSNS (1);
  	return true;
        }

@@ -4069,10 +4081,6 @@ xtensa_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
  	return true;
        }

-    case NEG:
-      *total = COSTS_N_INSNS (mode == DImode ? 4 : 2);
-      return true;
-
      case MULT:
        {
  	if (mode == SFmode)
@@ -4112,11 +4120,11 @@ xtensa_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
      case UMOD:
        {
  	if (mode == DImode)
-	  *total = COSTS_N_INSNS (50);
+	  *total = COSTS_N_INSNS (speed ? 100 : 50);
  	else if (TARGET_DIV32)
  	  *total = COSTS_N_INSNS (32);
  	else
-	  *total = COSTS_N_INSNS (50);
+	  *total = COSTS_N_INSNS (speed ? 100 : 50);
  	return true;
        }

@@ -4149,6 +4157,98 @@ xtensa_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
      }
  }

+static bool
+xtensa_is_insn_L32R_p(const rtx_insn *insn)
+{
+  rtx x = PATTERN (insn);
+
+  if (GET_CODE (x) == SET)
+    {
+      x = XEXP (x, 1);
+      if (GET_CODE (x) == MEM)
+	{
+	  x = XEXP (x, 0);
+	  return (GET_CODE (x) == SYMBOL_REF || CONST_INT_P (x))
+		 && CONSTANT_POOL_ADDRESS_P (x);
+	}
+    }
+
+  return false;
+}
+
+/* Compute a relative costs of RTL insns.  This is necessary in order to
+   achieve better RTL insn splitting/combination result.  */
+
+static int
+xtensa_insn_cost (rtx_insn *insn, bool speed)
+{
+  if (!(recog_memoized (insn) < 0))
+    {
+      int len = get_attr_length (insn), n = (len + 2) / 3;
+
+      if (len == 0)
+	return COSTS_N_INSNS (0);
+
+      if (speed)  /* For speed cost.  */
+	{
+	  /* "L32R" may be particular slow (implementation-dependent).  */
+	  if (xtensa_is_insn_L32R_p (insn))
+	    return COSTS_N_INSNS (1 + xtensa_extra_l32r_costs);
+
+	  /* Cost based on the pipeline model.  */
+	  switch (get_attr_type (insn))
+	    {
+	    case TYPE_STORE:
+	    case TYPE_MOVE:
+	    case TYPE_ARITH:
+	    case TYPE_MULTI:
+	    case TYPE_NOP:
+	    case TYPE_FSTORE:
+	      return COSTS_N_INSNS (n);
+
+	    case TYPE_LOAD:
+	      return COSTS_N_INSNS (n - 1 + 2);
+
+	    case TYPE_JUMP:
+	    case TYPE_CALL:
+	      return COSTS_N_INSNS (n - 1 + 3);
+
+	    case TYPE_FCONV:
+	    case TYPE_FLOAD:
+	    case TYPE_MUL16:
+	    case TYPE_MUL32:
+	    case TYPE_RSR:
+	      return COSTS_N_INSNS (n * 2);
+
+	    case TYPE_FMADD:
+	      return COSTS_N_INSNS (n * 4);
+
+	    case TYPE_DIV32:
+	      return COSTS_N_INSNS (n * 16);
+
+	    default:
+	      break;
+	    }
+	}
+      else  /* For size cost.  */
+	{
+	  /* Cost based on the instruction length.  */
+	  if (get_attr_type (insn) != TYPE_UNKNOWN)
+	    {
+	      /* "L32R" itself plus constant in litpool.  */
+	      if (xtensa_is_insn_L32R_p (insn))
+		return COSTS_N_INSNS (2) + 1;
+
+	      /* Consider ".n" short instructions.  */
+	      return COSTS_N_INSNS (n) - (n * 3 - len);
+	    }
+	}
+    }
+
+  /* Fall back.  */
+  return pattern_cost (PATTERN (insn), speed);
+}
+
  /* Worker function for TARGET_RETURN_IN_MEMORY.  */

  static bool
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 33cbd546de3..f6c6be4af24 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -98,7 +98,10 @@

  ;; Describe a user's asm statement.
  (define_asm_attributes
-  [(set_attr "type" "multi")])
+  [(set_attr "type"	"multi")
+   (set_attr "mode"	"none")
+   (set_attr "length"	"3")])  ;; Should be the maximum possible length
+				;; of a single machine instruction.

  \f
  ;; Pipeline model.
@@ -1879,7 +1882,10 @@
  }
    [(set_attr "type"	"jump")
     (set_attr "mode"	"none")
-   (set_attr "length"	"2")])
+   (set (attr "length")
+	(if_then_else (match_test "TARGET_DENSITY")
+		      (const_int 2)
+		      (const_int 3)))])

  \f
  ;; Miscellaneous instructions.
@@ -1934,7 +1940,10 @@
  }
    [(set_attr "type"	"nop")
     (set_attr "mode"	"none")
-   (set_attr "length"	"3")])
+   (set (attr "length")
+	(if_then_else (match_test "TARGET_DENSITY")
+		      (const_int 2)
+		      (const_int 3)))])

  (define_expand "nonlocal_goto"
    [(match_operand:SI 0 "general_operand" "")
@@ -1998,8 +2007,9 @@
    [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
    ""
    ""
-  [(set_attr "length" "0")
-   (set_attr "type" "nop")])
+  [(set_attr "type"	"nop")
+   (set_attr "mode"	"none")
+   (set_attr "length"	"0")])

  ;; Do not schedule instructions accessing memory before this point.

@@ -2018,7 +2028,9 @@
          (unspec:BLK [(match_operand:SI 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
    ""
    ""
-  [(set_attr "length" "0")])
+  [(set_attr "type"	"nop")
+   (set_attr "mode"	"none")
+   (set_attr "length"	"0")])

  (define_insn "trap"
    [(trap_if (const_int 1) (const_int 0))]
@@ -2031,7 +2043,10 @@
  }
    [(set_attr "type"	"trap")
     (set_attr "mode"	"none")
-   (set_attr "length"	"3")])
+   (set (attr "length")
+	(if_then_else (match_test "!TARGET_DEBUG && TARGET_DENSITY")
+		      (const_int 2)
+		      (const_int 3)))])

  ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
  ;; know if a frame pointer is required until the reload pass, and
diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
index 1fc68a3d994..08338e39060 100644
--- a/gcc/config/xtensa/xtensa.opt
+++ b/gcc/config/xtensa/xtensa.opt
@@ -30,6 +30,10 @@ mlongcalls
  Target Mask(LONGCALLS)
  Use indirect CALLXn instructions for large programs.

+mextra-l32r-costs=
+Target RejectNegative Joined UInteger Var(xtensa_extra_l32r_costs) Init(0)
+Set extra memory access cost for L32R instruction, in clock-cycle units.
+
  mtarget-align
  Target
  Automatically align branch targets to reduce branch penalties.
-- 
2.20.1

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 3/4] xtensa: Improve instruction cost estimation and suggestion
  2022-06-10  4:19 [PATCH 3/4] xtensa: Improve instruction cost estimation and suggestion Takayuki 'January June' Suwa
@ 2022-06-11 23:13 ` Max Filippov
  0 siblings, 0 replies; 2+ messages in thread
From: Max Filippov @ 2022-06-11 23:13 UTC (permalink / raw)
  To: Takayuki 'January June' Suwa; +Cc: GCC Patches

On Thu, Jun 9, 2022 at 9:26 PM Takayuki 'January June' Suwa
<jjsuwa_sys3175@yahoo.co.jp> wrote:
>
> This patch implements a new target-specific relative RTL insn cost function
> because of suboptimal cost estimation by default, and fixes several "length"
> insn attributes (related to the cost estimation).
>
> And also introduces a new machine-dependent option "-mextra-l32r-costs="
> that tells implementation-specific InstRAM/ROM access penalty for L32R
> instruction to the compiler (in clock-cycle units, 0 by default).
>
> gcc/ChangeLog:
>
>         * config/xtensa/xtensa.cc (xtensa_rtx_costs): Correct wrong case
>         for ABS and NEG, add missing case for BSWAP and CLRSB, and
>         double the costs for integer divisions using libfuncs if
>         optimizing for speed, in order to take advantage of fast constant
>         division by multiplication.
>         (TARGET_INSN_COST): New macro definition.
>         (xtensa_is_insn_L32R_p, xtensa_insn_cost): New functions for
>         calculating relative costs of a RTL insns, for both of speed and
>         size.
>         * config/xtensa/xtensa.md (return, nop, trap): Correct values of
>         the attribute "length" that depends on TARGET_DENSITY.
>         (define_asm_attributes, blockage, frame_blockage): Add missing
>         attributes.
>         * config/xtensa/xtensa.opt (-mextra-l32r-costs=): New machine-
>         dependent option, however, preparatory work for now.
> ---
>   gcc/config/xtensa/xtensa.cc  | 116 ++++++++++++++++++++++++++++++++---
>   gcc/config/xtensa/xtensa.md  |  29 ++++++---
>   gcc/config/xtensa/xtensa.opt |   4 ++
>   3 files changed, 134 insertions(+), 15 deletions(-)

Regtested for target=xtensa-linux-uclibc, no new regressions.
Committed to master.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-06-11 23:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-10  4:19 [PATCH 3/4] xtensa: Improve instruction cost estimation and suggestion Takayuki 'January June' Suwa
2022-06-11 23:13 ` Max Filippov

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).