This patch is a simplification of the previous patch to adjust the rtx insn
cost for prefixed instructions.  Rather than making it a separate function with
only one caller, I folded the code into rs6000_insn_cost.

You had asked for this to be a separate patch, so it is in this patch.

The basic problem is if there is no explicit cost predicate, rs6000_insn_cost
uses the instruction size to figure out how many instructions are present, and
make the cost a fact on that.  Since prefixed instructions are 12 bytes within
GCC (to deal with the implicit NOP), if we did not do this change, the
optimizers would try to save registers from prefixed loads because they thought
the load was more expensive.

Along with the other patches, I have done bootstraps on a little endian power8
system, and there were no regressions in the test suite.  Can I check this into
the trunk?

2019-10-08  Michael Meissner  <meiss...@linux.ibm.com>

        * config/rs6000/rs6000.c (rs6000_insn_cost): Do not make prefixed
        instructions cost more because they are larger in size.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 276715)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -20972,14 +20972,38 @@ rs6000_insn_cost (rtx_insn *insn, bool s
   if (recog_memoized (insn) < 0)
     return 0;
 
-  if (!speed)
-    return get_attr_length (insn);
+  if (speed)
+    {
+      int cost = get_attr_cost (insn);
+      if (cost > 0)
+       return cost;
+    }
 
-  int cost = get_attr_cost (insn);
-  if (cost > 0)
-    return cost;
+  int cost;
+  int length = get_attr_length (insn);
+  int n = length / 4;
+
+  /* How many real instructions are generated for this insn?  This is slightly
+     different from the length attribute, in that the length attribute counts
+     the number of bytes.  With prefixed instructions, we don't want to count a
+     prefixed instruction (length 12 bytes including possible NOP) as taking 3
+     instructions, but just one.  */
+  if (length >= 12 && get_attr_prefixed (insn) == PREFIXED_YES)
+    {
+      /* Single prefixed instruction.  */
+      if (length == 12)
+       n = 1;
+
+      /* A normal instruction and a prefixed instruction (16) or two back
+        to back prefixed instructions (20).  */
+      else if (length == 16 || length == 20)
+       n = 2;
+
+      /* Guess for larger instruction sizes.  */
+      else
+       n = 2 + (length - 20) / 4;
+    }
 
-  int n = get_attr_length (insn) / 4;
   enum attr_type type = get_attr_type (insn);
 
   switch (type)

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797

Reply via email to