diff mbox series

[RS6000] rs6000_rtx_costs multi-insn constants

Message ID 20200915011946.3395-6-amodra@gmail.com
State New
Headers show
Series [RS6000] rs6000_rtx_costs multi-insn constants | expand

Commit Message

Alan Modra Sept. 15, 2020, 1:19 a.m. UTC
This small patch to rs6000_rtx_const considerably improves code
generated for large constants in 64-bit code, teaching gcc that it is
better to load a constant from memory than to generate a sequence of
up to five dependent instructions.  Note that the rs6000 backend does
generate large constants as loads from memory at expand time but
optimisation passes replace them with SETs of the value due to not
having correct costs.

	PR 94393
	* config/rs6000/rs6000.c (rs6000_rtx_costs): Cost multi-insn
	constants.

Comments

Segher Boessenkool Sept. 16, 2020, 11:28 p.m. UTC | #1
On Tue, Sep 15, 2020 at 10:49:43AM +0930, Alan Modra wrote:
> This small patch to rs6000_rtx_const considerably improves code

(_costs)

> generated for large constants in 64-bit code, teaching gcc that it is
> better to load a constant from memory than to generate a sequence of
> up to five dependent instructions.  Note that the rs6000 backend does
> generate large constants as loads from memory at expand time but
> optimisation passes replace them with SETs of the value due to not
> having correct costs.
> 
> 	PR 94393
> 	* config/rs6000/rs6000.c (rs6000_rtx_costs): Cost multi-insn
> 	constants.

Okay for trunk.  Note that some p10 insns take a floating point
immediate, but those need to be handled specially anyway.

Thanks!


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5b3c0ee0e8c..8c300b82b11 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -21181,7 +21181,9 @@  rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
   switch (code)
     {
-      /* On the RS/6000, if it is valid in the insn, it is free.  */
+      /* (reg) is costed at zero by rtlanal.c:rtx_cost.  That sets a
+	 baseline for rtx costs:  If a constant is valid in an insn,
+	 it is free.  */
     case CONST_INT:
       if (((outer_code == SET
 	    || outer_code == PLUS
@@ -21242,6 +21244,17 @@  rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case CONST_DOUBLE:
     case CONST_WIDE_INT:
+      /* Subtract one insn here for consistency with the above code
+	 that returns one less than the actual number of insns for
+	 SETs.  Don't subtract one for other than SETs, because other
+	 operations will require the constant to be loaded to a
+	 register before performing the operation.  All special cases
+	 for codes other than SET must be handled before we get
+	 here.  */
+      *total = COSTS_N_INSNS (num_insns_constant (x, mode)
+			      - (outer_code == SET ? 1 : 0));
+      return true;
+
     case CONST:
     case HIGH:
     case SYMBOL_REF: