This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RS6000 6/7] Cost multi-insn constants


This small patch 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 five dependent
instructions.  Note that we already do this at expand time for plain
moves.  This change affects constants inside other RTL operations,
ie. those generated by various optimizations.

I would like to fix rtlanal.c:rtx_cost to not cost register moves at
zero, but that probably disrupts many targets.  See the comment.

	* config/rs6000/rs6000.c (rs6000_rtx_costs): Cost multi-insn
	CONST_INTs.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 941ad02..0218d0f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -30700,6 +30700,26 @@ 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.  This is because (set (reg1) (reg2)) is costed at zero
+	 by rtlanal.c:rtx_cost.  If we cost (set (reg) (const_int 0))
+	 at greater than the register move cost, then a call like
+	 foo (0, 0) will be implemented as li "r3,0; mr r4,r3; bl foo"
+	 rather than "li r3,0; li r4,0; bl foo".  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.
+	 FIXME: A call like foo (x - 1, x - 1) results in
+	 "addi r3,rx,-1; mr r4,r3; bl foo" rather than the better
+	 "addi r3,rx,-1; addi r4,rx,-1; bl foo" because rtx_cost
+	 returns zero for register moves.  This cannot be fixed by
+	 reducing the cost of PLUS and other arithmetic/logic codes
+	 to zero.  */
+      *total = COSTS_N_INSNS (num_insns_constant (x, mode)
+			      - (outer_code == SET ? 1 : 0));
+      return true;
+
     case CONST:
     case HIGH:
     case SYMBOL_REF:

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]