[middle-end] : Default the mode of pop and swap insns to the reg_raw_mode of FIRST_STACK_REG

Message ID CAFULd4YVerAL+r_a_CuvkeN91971CJF52BrUAof-ibAxNU1mFg@mail.gmail.com
State New
Headers show
Series
  • [middle-end] : Default the mode of pop and swap insns to the reg_raw_mode of FIRST_STACK_REG
Related show

Commit Message

Uros Bizjak Sept. 12, 2018, 6:34 p.m.
Hello!

Although reg-stack.c is mostly an x86 affair, attached patch decouples
it from x86 a bit. The patch changes the default mode of pop and swap
insns to the reg_raw_mode of FIRST_STACK_REG (= XFmode on x86). Also,
the patch explicitly constructs swap insn, without calling x86
specific named insn pattern.

2018-09-11  Uros Bizjak  <ubizjak@gmail.com>

    * reg-stack.c: Include regs.h.
    (replace_reg): Assert that mode is MODE_FLOAT or MODE_COMPLEX_FLOAT.
    (emit_pop_insn): Default pop insn mode to the reg_raw_mode of
    FIRST_STACK_REG, not DFmode.
    (emit_swap_insn): Default swap insn mode to the reg_raw_mode of
    FIRST_STACK_REG, not XFmode.  Explicitly construct swap RTX.
    (change stack): Default register mode to the reg_raw_mode of
    FIRST_STACK_REG, not DFmode.
    * config/i386/i386.md (*swap<mode>): Remove insn pattern.
    (*swapxf): Rename from swapxf.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

No functional changes, but the patch needs middle-end approval.

OK for mainline?

Uros.

Comments

Jeff Law Sept. 13, 2018, 6:45 a.m. | #1
On 9/12/18 12:34 PM, Uros Bizjak wrote:
> Hello!

> 

> Although reg-stack.c is mostly an x86 affair, attached patch decouples

> it from x86 a bit. The patch changes the default mode of pop and swap

> insns to the reg_raw_mode of FIRST_STACK_REG (= XFmode on x86). Also,

> the patch explicitly constructs swap insn, without calling x86

> specific named insn pattern.

> 

> 2018-09-11  Uros Bizjak  <ubizjak@gmail.com>

> 

>     * reg-stack.c: Include regs.h.

>     (replace_reg): Assert that mode is MODE_FLOAT or MODE_COMPLEX_FLOAT.

>     (emit_pop_insn): Default pop insn mode to the reg_raw_mode of

>     FIRST_STACK_REG, not DFmode.

>     (emit_swap_insn): Default swap insn mode to the reg_raw_mode of

>     FIRST_STACK_REG, not XFmode.  Explicitly construct swap RTX.

>     (change stack): Default register mode to the reg_raw_mode of

>     FIRST_STACK_REG, not DFmode.

>     * config/i386/i386.md (*swap<mode>): Remove insn pattern.

>     (*swapxf): Rename from swapxf.

> 

> Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

> 

> No functional changes, but the patch needs middle-end approval.

> 

> OK for mainline?

OK.
jeff

Patch

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1e7241c87c2..ab1237e23da 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3864,7 +3864,7 @@ 
     operands[1] = CONST1_RTX (<MODE>mode);
 })
 
-(define_insn "swapxf"
+(define_insn "*swapxf"
   [(set (match_operand:XF 0 "register_operand" "+f")
 	(match_operand:XF 1 "register_operand" "+f"))
    (set (match_dup 1)
@@ -3878,22 +3878,8 @@ 
 }
   [(set_attr "type" "fxch")
    (set_attr "mode" "XF")])
-
-(define_insn "*swap<mode>"
-  [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
-	(match_operand:MODEF 1 "fp_register_operand" "+f"))
-   (set (match_dup 1)
-	(match_dup 0))]
-  "TARGET_80387 || reload_completed"
-{
-  if (STACK_TOP_P (operands[0]))
-    return "fxch\t%1";
-  else
-    return "fxch\t%0";
-}
-  [(set_attr "type" "fxch")
-   (set_attr "mode" "<MODE>")])
 
+
 ;; Zero extension instructions
 
 (define_expand "zero_extendsidi2"
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index d97a358e3f8..97d758c8307 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -162,6 +162,7 @@ 
 #include "df.h"
 #include "insn-config.h"
 #include "memmodel.h"
+#include "regs.h"
 #include "emit-rtl.h"  /* FIXME: Can go away once crtl is moved to rtl.h.  */
 #include "recog.h"
 #include "varasm.h"
@@ -711,7 +712,7 @@  replace_reg (rtx *reg, int regno)
   gcc_assert (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG));
   gcc_assert (STACK_REG_P (*reg));
 
-  gcc_assert (SCALAR_FLOAT_MODE_P (GET_MODE (*reg))
+  gcc_assert (GET_MODE_CLASS (GET_MODE (*reg)) == MODE_FLOAT
 	      || GET_MODE_CLASS (GET_MODE (*reg)) == MODE_COMPLEX_FLOAT);
 
   *reg = FP_MODE_REG (regno, GET_MODE (*reg));
@@ -765,8 +766,10 @@  get_hard_regnum (stack_ptr regstack, rtx reg)
    cases the movdf pattern to pop.  */
 
 static rtx_insn *
-emit_pop_insn (rtx_insn *insn, stack_ptr regstack, rtx reg, enum emit_where where)
+emit_pop_insn (rtx_insn *insn, stack_ptr regstack, rtx reg,
+	       enum emit_where where)
 {
+  machine_mode raw_mode = reg_raw_mode[FIRST_STACK_REG];
   rtx_insn *pop_insn;
   rtx pop_rtx;
   int hard_regno;
@@ -775,8 +778,8 @@  emit_pop_insn (rtx_insn *insn, stack_ptr regstack, rtx reg, enum emit_where wher
      CLOBBER and USE expressions.  */
   if (COMPLEX_MODE_P (GET_MODE (reg)))
     {
-      rtx reg1 = FP_MODE_REG (REGNO (reg), DFmode);
-      rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, DFmode);
+      rtx reg1 = FP_MODE_REG (REGNO (reg), raw_mode);
+      rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, raw_mode);
 
       pop_insn = NULL;
       if (get_hard_regnum (regstack, reg1) >= 0)
@@ -791,15 +794,15 @@  emit_pop_insn (rtx_insn *insn, stack_ptr regstack, rtx reg, enum emit_where wher
 
   gcc_assert (hard_regno >= FIRST_STACK_REG);
 
-  pop_rtx = gen_rtx_SET (FP_MODE_REG (hard_regno, DFmode),
-			 FP_MODE_REG (FIRST_STACK_REG, DFmode));
+  pop_rtx = gen_rtx_SET (FP_MODE_REG (hard_regno, raw_mode),
+			 FP_MODE_REG (FIRST_STACK_REG, raw_mode));
 
   if (where == EMIT_AFTER)
     pop_insn = emit_insn_after (pop_rtx, insn);
   else
     pop_insn = emit_insn_before (pop_rtx, insn);
 
-  add_reg_note (pop_insn, REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, DFmode));
+  add_reg_note (pop_insn, REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, raw_mode));
 
   regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
     = regstack->reg[regstack->top];
@@ -820,7 +823,6 @@  static void
 emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg)
 {
   int hard_regno;
-  rtx swap_rtx;
   int other_reg;		/* swap regno temps */
   rtx_insn *i1;			/* the stack-reg insn prior to INSN */
   rtx i1set = NULL_RTX;		/* the SET rtx within I1 */
@@ -978,9 +980,13 @@  emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg)
       return;
     }
 
-  swap_rtx = gen_swapxf (FP_MODE_REG (hard_regno, XFmode),
-			 FP_MODE_REG (FIRST_STACK_REG, XFmode));
-
+  machine_mode raw_mode = reg_raw_mode[FIRST_STACK_REG];
+  rtx op1 = FP_MODE_REG (hard_regno, raw_mode);
+  rtx op2 = FP_MODE_REG (FIRST_STACK_REG, raw_mode);
+  rtx swap_rtx
+    = gen_rtx_PARALLEL (VOIDmode,
+			gen_rtvec (2, gen_rtx_SET (op1, op2),
+				   gen_rtx_SET (op2, op1)));
   if (i1)
     emit_insn_after (swap_rtx, i1);
   else if (current_block)
@@ -2487,6 +2493,7 @@  change_stack (rtx_insn *insn, stack_ptr old, stack_ptr new_stack,
 	      enum emit_where where)
 {
   int reg;
+  machine_mode raw_mode = reg_raw_mode[FIRST_STACK_REG];
   rtx_insn *update_end = NULL;
   int i;
 
@@ -2588,7 +2595,7 @@  change_stack (rtx_insn *insn, stack_ptr old, stack_ptr new_stack,
 		next--;
 	      dest = next--;
 	    }
-	  emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], DFmode),
+	  emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], raw_mode),
 			 EMIT_BEFORE);
 	}
     }
@@ -2610,11 +2617,11 @@  change_stack (rtx_insn *insn, stack_ptr old, stack_ptr new_stack,
 	  {
 	    while (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[next]))
 	      next--;
-	    emit_pop_insn (insn, old, FP_MODE_REG (old->reg[next], DFmode),
+	    emit_pop_insn (insn, old, FP_MODE_REG (old->reg[next], raw_mode),
 			   EMIT_BEFORE);
 	  }
 	else
-	  emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], DFmode),
+	  emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], raw_mode),
 			 EMIT_BEFORE);
     }
 
@@ -2661,7 +2668,7 @@  change_stack (rtx_insn *insn, stack_ptr old, stack_ptr new_stack,
 		gcc_assert (reg != -1);
 
 		emit_swap_insn (insn, old,
-				FP_MODE_REG (old->reg[reg], DFmode));
+				FP_MODE_REG (old->reg[reg], raw_mode));
 	      }
 
 	    /* See if any regs remain incorrect.  If so, bring an
@@ -2672,7 +2679,7 @@  change_stack (rtx_insn *insn, stack_ptr old, stack_ptr new_stack,
 	      if (new_stack->reg[reg] != old->reg[reg])
 		{
 		  emit_swap_insn (insn, old,
-				  FP_MODE_REG (old->reg[reg], DFmode));
+				  FP_MODE_REG (old->reg[reg], raw_mode));
 		  break;
 		}
 	  } while (reg >= 0);