public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-3105] Tweak -Os costs for scalar-to-vector pass.
@ 2021-08-24  2:05 Roger Sayle
  0 siblings, 0 replies; only message in thread
From: Roger Sayle @ 2021-08-24  2:05 UTC (permalink / raw)
  To: gcc-cvs

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

commit r12-3105-gf8977166135de09fe36a3b57cc11daa67587604e
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Tue Aug 24 03:04:48 2021 +0100

    Tweak -Os costs for scalar-to-vector pass.
    
    Back in June I briefly mentioned in one of my gcc-patches posts that
    a change that should have always reduced code size, would mysteriously
    occasionally result in slightly larger code (according to CSiBE):
    https://gcc.gnu.org/pipermail/gcc-patches/2021-June/573233.html
    
    Investigating further, the cause turns out to be that x86_64's
    scalar-to-vector (stv) pass is relying on poor estimates of the size
    costs/benefits.  This patch tweaks the backend's compute_convert_gain
    method to provide slightly more accurate values when compiling with
    -Os. Compilation without -Os is (should be) unaffected.  And for
    completeness, I'll mention that the stv pass is a net win for code
    size so it's much better to improve its heuristics than simply gate
    the pass on !optimize_for_size.
    
    The net effect of this change is to save 1399 bytes on the CSiBE
    code size benchmark when compiling with -Os.
    
    2021-08-24  Roger Sayle  <roger@nextmovesoftware.com>
                Richard Biener  <rguenther@suse.de>
    
    gcc/ChangeLog
            * config/i386/i386-features.c (compute_convert_gain): Provide
            more accurate values for CONST_INT, when optimizing for size.
            * config/i386/i386.c (COSTS_N_BYTES): Move definition from here...
            * config/i386/i386.h (COSTS_N_BYTES): to here.

Diff:
---
 gcc/config/i386/i386-features.c | 38 +++++++++++++++++++++++++++++++++-----
 gcc/config/i386/i386.c          |  2 --
 gcc/config/i386/i386.h          |  5 +++++
 3 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c
index d9c6652d1c9..5a99ea7c046 100644
--- a/gcc/config/i386/i386-features.c
+++ b/gcc/config/i386/i386-features.c
@@ -610,12 +610,40 @@ general_scalar_chain::compute_convert_gain ()
 
 	  case CONST_INT:
 	    if (REG_P (dst))
-	      /* DImode can be immediate for TARGET_64BIT and SImode always.  */
-	      igain += m * COSTS_N_INSNS (1);
+	      {
+		if (optimize_insn_for_size_p ())
+		  {
+		    /* xor (2 bytes) vs. xorps (3 bytes).  */
+		    if (src == const0_rtx)
+		      igain -= COSTS_N_BYTES (1);
+		    /* movdi_internal vs. movv2di_internal.  */
+		    /* => mov (5 bytes) vs. movaps (7 bytes).  */
+		    else if (x86_64_immediate_operand (src, SImode))
+		      igain -= COSTS_N_BYTES (2);
+		    else
+		      /* ??? Larger immediate constants are placed in the
+			 constant pool, where the size benefit/impact of
+			 STV conversion is affected by whether and how
+			 often each constant pool entry is shared/reused.
+			 The value below is empirically derived from the
+			 CSiBE benchmark (and the optimal value may drift
+			 over time).  */
+		      igain += COSTS_N_BYTES (0);
+		  }
+		else
+		  {
+		    /* DImode can be immediate for TARGET_64BIT
+		       and SImode always.  */
+		    igain += m * COSTS_N_INSNS (1);
+		    igain -= vector_const_cost (src);
+		  }
+	      }
 	    else if (MEM_P (dst))
-	      igain += (m * ix86_cost->int_store[2]
-			- ix86_cost->sse_store[sse_cost_idx]);
-	    igain -= vector_const_cost (src);
+	      {
+		igain += (m * ix86_cost->int_store[2]
+			  - ix86_cost->sse_store[sse_cost_idx]);
+		igain -= vector_const_cost (src);
+	      }
 	    break;
 
 	  default:
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 46844fab08f..5bff131f6d9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -19982,8 +19982,6 @@ ix86_division_cost (const struct processor_costs *cost,
     return cost->divide[MODE_INDEX (mode)];
 }
 
-#define COSTS_N_BYTES(N) ((N) * 2)
-
 /* Return cost of shift in MODE.
    If CONSTANT_OP1 is true, the op1 value is known and set in OP1_VAL.
    AND_IN_OP1 specify in op1 is result of and and SHIFT_AND_TRUNCATE
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 8aba86d11b4..11ac8d01100 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -88,6 +88,11 @@ struct stringop_algs
   } size [MAX_STRINGOP_ALGS];
 };
 
+/* Analog of COSTS_N_INSNS when optimizing for size.  */
+#ifndef COSTS_N_BYTES
+#define COSTS_N_BYTES(N) ((N) * 2)
+#endif
+
 /* Define the specific costs for a given cpu.  NB: hard_register is used
    by TARGET_REGISTER_MOVE_COST and TARGET_MEMORY_MOVE_COST to compute
    hard register move costs by register allocator.  Relative costs of


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

only message in thread, other threads:[~2021-08-24  2:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-24  2:05 [gcc r12-3105] Tweak -Os costs for scalar-to-vector pass 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).