diff mbox series

[6/8,RS6000] rs6000_rtx_costs multi-insn constants

Message ID 20201007225800.9536-7-amodra@gmail.com
State New
Headers show
Series rs6000_rtx_costs V2 | expand

Commit Message

Alan Modra Oct. 7, 2020, 10:57 p.m. UTC
This small patch to rs6000_rtx_costs 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.
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 15a806fe307..76aedbfae6f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -21343,7 +21343,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
@@ -21404,6 +21406,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: