Hi,
while working on the GCN port I ended up with many redundant register copies
of the form
 mov reg, exec
 do something
 mov reg, exec
 do something
 ...
these copies are generated by LRA because exec is small register class and needs
a lot of reloading (it could be improved too, but I do not care because I want
to handle exec specially later anyway).

I was however suprised this garbage survives postreload optimizations.  It is 
easy
to fix in regcprop which already does some noop copy elimination, but only
of the for mov reg, reg after substituting.

This patch implements it and eliminates many movs while running testsuite.
Bootstrapped/regtested x86_64-linux, OK?

Honza

Index: regcprop.c
===================================================================
--- regcprop.c  (revision 240109)
+++ regcprop.c  (working copy)
@@ -771,6 +771,25 @@ copyprop_hardreg_forward_1 (basic_block
        }
 
       set = single_set (insn);
+
+      /* Detect noop sets and remove them before processing side effects.  */
+      if (set && REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)))
+       {
+         unsigned int regno = REGNO (SET_SRC (set));
+         rtx r1 = find_oldest_value_reg (REGNO_REG_CLASS (regno),
+                                         SET_DEST (set), vd);
+         rtx r2 = find_oldest_value_reg (REGNO_REG_CLASS (regno),
+                                         SET_SRC (set), vd);
+         if (rtx_equal_p (r1 ? r1 : SET_DEST (set), r2 ? r2 : SET_SRC (set)))
+           {
+             bool last = insn == BB_END (bb);
+             delete_insn (insn);
+             if (last)
+               break;
+             continue;
+           }
+       }
+
       extract_constrain_insn (insn);
       preprocess_constraints (insn);
       const operand_alternative *op_alt = which_op_alt ();
@@ -860,7 +879,9 @@ copyprop_hardreg_forward_1 (basic_block
             register in the same class.  */
          if (REG_P (SET_DEST (set)))
            {
-             new_rtx = find_oldest_value_reg (REGNO_REG_CLASS (regno), src, 
vd);
+             new_rtx = find_oldest_value_reg (REGNO_REG_CLASS (regno),
+                                              src, vd);
+
              if (new_rtx && validate_change (insn, &SET_SRC (set), new_rtx, 0))
                {
                  if (dump_file)

Reply via email to