On Fri, May 12, 2017 at 8:34 PM, Jeff Law <l...@redhat.com> wrote:
> On 05/10/2017 01:05 PM, Uros Bizjak wrote:
>>
>> On Wed, May 10, 2017 at 5:18 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
>>>
>>> On Wed, May 10, 2017 at 4:27 PM, Jakub Jelinek <ja...@redhat.com> wrote:
>>>>
>>>> On Tue, May 09, 2017 at 06:06:47PM +0200, Uros Bizjak wrote:
>>>>>
>>>>> Attached patch enables post-reload compare elimination pass by
>>>>> providing expected patterns (duplicates of existing patterns with
>>>>> setters of reg and flags switched in the parallel) for flag setting
>>>>> arithmetic instructions.
>>>>>
>>>>> The merge triggers more than 3000 times during the gcc bootstrap,
>>>>> mostly in cases where intervening memory load or store prevents
>>>>> combine from merging the arithmetic insn and the following compare.
>>>>>
>>>>> Also, some recent linux x86_64 defconfig build results in ~200 merges,
>>>>> removing ~200 test/cmp insns. Not much, but I think the results still
>>>>> warrant the pass to be enabled.
>>>>
>>>>
>>>> Isn't the right fix instead to change the compare-elim.c pass to either
>>>> accept both reg vs. flags orderings in parallel, or both depending
>>>> on some target hook, or change it to the order i386.md and most other
>>>> major targets use and just fix up mn10300/rx (and aarch64?) to use the
>>>> same
>>>> order?
>>
>>
>> Attached patch changes compare-elim.c order to what i386.md expects.
>>
>> Thoughts?
>
> I think with an appropriate change to the canonicalization rules in the
> manual this is fine.
>
> I've got the visium, rx and mn103 patches handy to ensure they don't
> regress.  aarch64 doesn't seem to be affected either way but I didn't
> investigate why -- I expected it to improve with your change.
>
> I'll write up a ChangeLog and commit the mn103, rx and visium changes after
> you commit the compare-elim & documentation bits.

Thanks!

I went ahead and commit the patch without documentation change (which
I plan to submit in a separate patch ASAP), with the following
ChangeLog:

2017-05-12  Uros Bizjak  <ubiz...@gmail.com>

    * compare-elim.c (try_eliminate_compare): Canonicalize
    operation with embedded compare to
    [(set (reg:CCM) (compare:CCM (operation) (immediate)))
     (set (reg) (operation)].

    * config/i386/i386.c (TARGET_FLAGS_REGNUM): New define.

Re-bootstrapped and re-tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c  (revision 247978)
+++ config/i386/i386.c  (working copy)
@@ -51805,6 +51826,8 @@ ix86_run_selftests (void)
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST ix86_address_cost
 
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM FLAGS_REG
 #undef TARGET_FIXED_CONDITION_CODE_REGS
 #define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
 #undef TARGET_CC_MODES_COMPATIBLE
Index: compare-elim.c
===================================================================
--- compare-elim.c      (revision 247978)
+++ compare-elim.c      (working copy)
@@ -45,9 +45,9 @@ along with GCC; see the file COPYING3.  If not see
    (3) If an insn of form (2) can usefully set the flags, there is
        another pattern of the form
 
-       [(set (reg) (operation)
-        (set (reg:CCM) (compare:CCM (operation) (immediate)))]
-
+       [(set (reg:CCM) (compare:CCM (operation) (immediate)))
+        (set (reg) (operation)]
+        
        The mode CCM will be chosen as if by SELECT_CC_MODE.
 
    Note that unlike NOTICE_UPDATE_CC, we do not handle memory operands.
@@ -582,7 +582,7 @@ equivalent_reg_at_start (rtx reg, rtx_insn *end, r
 static bool
 try_eliminate_compare (struct comparison *cmp)
 {
-  rtx x, flags, in_a, in_b, cmp_src;
+  rtx flags, in_a, in_b, cmp_src;
 
   /* We must have found an interesting "clobber" preceding the compare.  */
   if (cmp->prev_clobber == NULL)
@@ -628,7 +628,8 @@ try_eliminate_compare (struct comparison *cmp)
      Validate that PREV_CLOBBER itself does in fact refer to IN_A.  Do
      recall that we've already validated the shape of PREV_CLOBBER.  */
   rtx_insn *insn = cmp->prev_clobber;
-  x = XVECEXP (PATTERN (insn), 0, 0);
+
+  rtx x = XVECEXP (PATTERN (insn), 0, 0);
   if (rtx_equal_p (SET_DEST (x), in_a))
     cmp_src = SET_SRC (x);
 
@@ -666,13 +667,24 @@ try_eliminate_compare (struct comparison *cmp)
     flags = gen_rtx_REG (cmp->orig_mode, targetm.flags_regnum);
 
   /* Generate a new comparison for installation in the setter.  */
-  x = copy_rtx (cmp_src);
-  x = gen_rtx_COMPARE (GET_MODE (flags), x, in_b);
-  x = gen_rtx_SET (flags, x);
+  rtx y = copy_rtx (cmp_src);
+  y = gen_rtx_COMPARE (GET_MODE (flags), y, in_b);
+  y = gen_rtx_SET (flags, y);
 
+  /* Canonicalize instruction to:
+     [(set (reg:CCM) (compare:CCM (operation) (immediate)))
+      (set (reg) (operation)]  */
+
+  rtvec v = rtvec_alloc (2);
+  RTVEC_ELT (v, 0) = y;
+  RTVEC_ELT (v, 1) = x;
+  
+  rtx pat = gen_rtx_PARALLEL (VOIDmode, v);
+  
   /* Succeed if the new instruction is valid.  Note that we may have started
      a change group within maybe_select_cc_mode, therefore we must continue. */
-  validate_change (insn, &XVECEXP (PATTERN (insn), 0, 1), x, true);
+  validate_change (insn, &PATTERN (insn), pat, true);
+  
   if (!apply_change_group ())
     return false;
 

Reply via email to