I was asked to split V4 patch #4.2 into smaller chuncks.  This patch is one of
8 patches that were broken out from 4.2.  Another patch from 4.2 to use
SIGNED_16BIT_OFFSET_EXTRA_P has already been committed.

This patch adjusts the insn cost to treat prefixed instructions the same as
non-prefixed instructions, rather than making them seem 3 times as expensive,
since the prefixed instruction length is 12 bytes compared to the normal 4
bytes.

Using all of the patches in this series, I have bootstrapped the compiler on a
little endian power8 system and ran the regression tests.  In addition, I have
built the Spec 2006 and 2017 benchmark suites, for -mcpu=power8, -mcpu=power9,
and -mcpu=future, and all of the benchmarks build.  Can I check this into the
trunk?

2019-10-03  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 276535)
+++ 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