public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-1052] xtensa: Improve instruction cost estimation and suggestion
@ 2022-06-11 23:12 Max Filippov
  0 siblings, 0 replies; only message in thread
From: Max Filippov @ 2022-06-11 23:12 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ccd02e734e0f1742629403b46e5b1c650b00fd65

commit r13-1052-gccd02e734e0f1742629403b46e5b1c650b00fd65
Author: Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Date:   Fri Jun 10 13:19:32 2022 +0900

    xtensa: Improve instruction cost estimation and suggestion
    
    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.

Diff:
---
 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 bc3330f836f..597a36e1a97 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
 
@@ -3937,7 +3941,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);
 
@@ -4025,9 +4029,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;
@@ -4051,13 +4060,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;
       }
 
@@ -4073,10 +4085,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)
@@ -4116,11 +4124,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;
       }
 
@@ -4153,6 +4161,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.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-11 23:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-11 23:12 [gcc r13-1052] xtensa: Improve instruction cost estimation and suggestion 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).