Hello!

This patch merges 64-bit and 32-bit gotoff_operand code paths in
legitimize_pic_address. Also, the patch uses copy_to_suggested_reg,
which seems to be invented just for this purpose. Also,
expand_simple_binop will ouput to suggested target reg by itself, so
there is no need to emit separate move insn.

2016-05-10  Uros Bizjak  <ubiz...@gmail.com>

    * config/i386/i386.c (legitimize_pic_address): Merge 64-bit and 32-bit
    gotoff_operand code paths.  Use copy_to_suggested_regs and
    expand_simple_binop where appropriate.  Cleanup.

Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 05476f3..3f02c8e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -15375,46 +15375,18 @@ legitimize_pic_address (rtx orig, rtx reg)
 
   if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
     new_rtx = addr;
-  else if (TARGET_64BIT && !TARGET_PECOFF
-          && ix86_cmodel != CM_SMALL_PIC && gotoff_operand (addr, Pmode))
-    {
-      rtx tmpreg;
-      /* This symbol may be referenced via a displacement from the PIC
-        base address (@GOTOFF).  */
 
-      if (GET_CODE (addr) == CONST)
-       addr = XEXP (addr, 0);
-      if (GET_CODE (addr) == PLUS)
-         {
-            new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
-                                     UNSPEC_GOTOFF);
-           new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
-         }
-       else
-          new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
-      new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-      if (!reg)
-        tmpreg = gen_reg_rtx (Pmode);
-      else
-       tmpreg = reg;
-      emit_move_insn (tmpreg, new_rtx);
-
-      if (reg != 0)
-       {
-         new_rtx = expand_simple_binop (Pmode, PLUS, reg, pic_offset_table_rtx,
-                                        tmpreg, 1, OPTAB_DIRECT);
-         new_rtx = reg;
-       }
-      else
-        new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
-    }
-  else if (!TARGET_64BIT && !TARGET_PECOFF && gotoff_operand (addr, Pmode))
+  else if ((!TARGET_64BIT
+           || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
+          && !TARGET_PECOFF
+          && gotoff_operand (addr, Pmode))
     {
       /* This symbol may be referenced via a displacement from the PIC
         base address (@GOTOFF).  */
 
       if (GET_CODE (addr) == CONST)
        addr = XEXP (addr, 0);
+
       if (GET_CODE (addr) == PLUS)
          {
             new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
@@ -15423,14 +15395,20 @@ legitimize_pic_address (rtx orig, rtx reg)
          }
        else
           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
+
       new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-      new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
+
+      if (TARGET_64BIT)
+       new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
 
       if (reg != 0)
        {
-         emit_move_insn (reg, new_rtx);
-         new_rtx = reg;
-       }
+         gcc_assert (REG_P (reg));
+         new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
+                                        new_rtx, reg, 1, OPTAB_DIRECT);
+       }
+      else
+       new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
     }
   else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
           /* We can't use @GOTOFF for text labels on VxWorks;
@@ -15448,14 +15426,12 @@ legitimize_pic_address (rtx orig, rtx reg)
          new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
          new_rtx = gen_rtx_CONST (Pmode, new_rtx);
 
-         if (reg == 0)
-           reg = gen_reg_rtx (Pmode);
-         emit_move_insn (reg, new_rtx);
-         new_rtx = reg;
+         new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
        }
       else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
        {
-         new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 
UNSPEC_GOTPCREL);
+         new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
+                                   UNSPEC_GOTPCREL);
          new_rtx = gen_rtx_CONST (Pmode, new_rtx);
          new_rtx = gen_const_mem (Pmode, new_rtx);
          set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
@@ -15481,25 +15457,15 @@ legitimize_pic_address (rtx orig, rtx reg)
          new_rtx = gen_const_mem (Pmode, new_rtx);
          set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
 
-         if (reg == 0)
-           reg = gen_reg_rtx (Pmode);
-         emit_move_insn (reg, new_rtx);
-         new_rtx = reg;
+         new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
        }
     }
   else
     {
       if (CONST_INT_P (addr)
          && !x86_64_immediate_operand (addr, VOIDmode))
-       {
-         if (reg)
-           {
-             emit_move_insn (reg, addr);
-             new_rtx = reg;
-           }
-         else
-           new_rtx = force_reg (Pmode, addr);
-       }
+       new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
+
       else if (GET_CODE (addr) == CONST)
        {
          addr = XEXP (addr, 0);
@@ -15513,13 +15479,15 @@ legitimize_pic_address (rtx orig, rtx reg)
            return orig;
          gcc_assert (GET_CODE (addr) == PLUS);
        }
+
       if (GET_CODE (addr) == PLUS)
        {
          rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
 
          /* Check first to see if this is a constant offset from a @GOTOFF
             symbol reference.  */
-         if (!TARGET_PECOFF && gotoff_operand (op0, Pmode)
+         if (!TARGET_PECOFF
+             && gotoff_operand (op0, Pmode)
              && CONST_INT_P (op1))
            {
              if (!TARGET_64BIT)
@@ -15528,13 +15496,18 @@ legitimize_pic_address (rtx orig, rtx reg)
                                            UNSPEC_GOTOFF);
                  new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
                  new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-                 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
 
                  if (reg != 0)
                    {
-                     emit_move_insn (reg, new_rtx);
-                     new_rtx = reg;
+                     gcc_assert (REG_P (reg));
+                     new_rtx = expand_simple_binop (Pmode, PLUS,
+                                                    pic_offset_table_rtx,
+                                                    new_rtx, reg, 1,
+                                                    OPTAB_DIRECT);
                    }
+                 else
+                   new_rtx
+                     = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
                }
              else
                {
@@ -15543,7 +15516,9 @@ legitimize_pic_address (rtx orig, rtx reg)
                    {
                      if (!x86_64_immediate_operand (op1, Pmode))
                        op1 = force_reg (Pmode, op1);
-                     new_rtx = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), 
op1);
+
+                     new_rtx
+                       = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
                    }
                }
            }
@@ -15561,6 +15536,7 @@ legitimize_pic_address (rtx orig, rtx reg)
                    {
                      if (!x86_64_immediate_operand (new_rtx, mode))
                        new_rtx = force_reg (mode, new_rtx);
+
                      new_rtx
                        = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
                    }

Reply via email to