2019-08-27 Richard Biener <rguenther@suse.de>
authorRichard Biener <rguenther@suse.de>
Tue, 27 Aug 2019 12:46:07 +0000 (12:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 27 Aug 2019 12:46:07 +0000 (12:46 +0000)
* config/i386/i386-features.h
(general_scalar_chain::~general_scalar_chain): Add.
(general_scalar_chain::insns_conv): New bitmap.
(general_scalar_chain::n_sse_to_integer): New.
(general_scalar_chain::n_integer_to_sse): Likewise.
(general_scalar_chain::make_vector_copies): Adjust signature.
* config/i386/i386-features.c
(general_scalar_chain::general_scalar_chain): Outline,
initialize new members.
(general_scalar_chain::~general_scalar_chain): New.
(general_scalar_chain::mark_dual_mode_def): Record insns
we need to insert conversions at and count them.
(general_scalar_chain::compute_convert_gain): Account
for conversion instructions at chain boundary.
(general_scalar_chain::make_vector_copies): Generate a single
copy for a def by a specific insn.
(general_scalar_chain::convert_registers): First populate
defs_map, then make copies at out-of chain insns.

From-SVN: r274953

gcc/ChangeLog
gcc/config/i386/i386-features.c
gcc/config/i386/i386-features.h

index b7c0fbe..65f9db9 100644 (file)
@@ -1,3 +1,24 @@
+2019-08-27  Richard Biener  <rguenther@suse.de>
+
+       * config/i386/i386-features.h
+       (general_scalar_chain::~general_scalar_chain): Add.
+       (general_scalar_chain::insns_conv): New bitmap.
+       (general_scalar_chain::n_sse_to_integer): New.
+       (general_scalar_chain::n_integer_to_sse): Likewise.
+       (general_scalar_chain::make_vector_copies): Adjust signature.
+       * config/i386/i386-features.c
+       (general_scalar_chain::general_scalar_chain): Outline,
+       initialize new members.
+       (general_scalar_chain::~general_scalar_chain): New.
+       (general_scalar_chain::mark_dual_mode_def): Record insns
+       we need to insert conversions at and count them.
+       (general_scalar_chain::compute_convert_gain): Account
+       for conversion instructions at chain boundary.
+       (general_scalar_chain::make_vector_copies): Generate a single
+       copy for a def by a specific insn.
+       (general_scalar_chain::convert_registers): First populate
+       defs_map, then make copies at out-of chain insns.
+
 2019-08-27  Richard Earnshaw  <rearnsha@arm.com>
 
        * config/arm/arm.md (stack_protect_set_insn): Add security-related
index 5891584..9505b4a 100644 (file)
@@ -320,6 +320,20 @@ scalar_chain::add_to_queue (unsigned insn_uid)
   bitmap_set_bit (queue, insn_uid);
 }
 
+general_scalar_chain::general_scalar_chain (enum machine_mode smode_,
+                                           enum machine_mode vmode_)
+     : scalar_chain (smode_, vmode_)
+{
+  insns_conv = BITMAP_ALLOC (NULL);
+  n_sse_to_integer = 0;
+  n_integer_to_sse = 0;
+}
+
+general_scalar_chain::~general_scalar_chain ()
+{
+  BITMAP_FREE (insns_conv);
+}
+
 /* For DImode conversion, mark register defined by DEF as requiring
    conversion.  */
 
@@ -328,15 +342,27 @@ general_scalar_chain::mark_dual_mode_def (df_ref def)
 {
   gcc_assert (DF_REF_REG_DEF_P (def));
 
-  if (bitmap_bit_p (defs_conv, DF_REF_REGNO (def)))
-    return;
-
+  /* Record the def/insn pair so we can later efficiently iterate over
+     the defs to convert on insns not in the chain.  */
+  bool reg_new = bitmap_set_bit (defs_conv, DF_REF_REGNO (def));
+  if (!bitmap_bit_p (insns, DF_REF_INSN_UID (def)))
+    {
+      if (!bitmap_set_bit (insns_conv, DF_REF_INSN_UID (def))
+         && !reg_new)
+       return;
+      n_integer_to_sse++;
+    }
+  else
+    {
+      if (!reg_new)
+       return;
+      n_sse_to_integer++;
+    }
   if (dump_file)
     fprintf (dump_file,
             "  Mark r%d def in insn %d as requiring both modes in chain #%d\n",
             DF_REF_REGNO (def), DF_REF_INSN_UID (def), chain_id);
-
-  bitmap_set_bit (defs_conv, DF_REF_REGNO (def));
 }
 
 /* For TImode conversion, it is unused.  */
@@ -523,7 +549,7 @@ general_scalar_chain::compute_convert_gain ()
               || GET_CODE (src) == ASHIFTRT
               || GET_CODE (src) == LSHIFTRT)
        {
-         if (CONST_INT_P (XEXP (src, 0)))
+         if (CONST_INT_P (XEXP (src, 0)))
            igain -= vector_const_cost (XEXP (src, 0));
          igain += m * ix86_cost->shift_const - ix86_cost->sse_op;
          if (INTVAL (XEXP (src, 1)) >= 32)
@@ -588,9 +614,12 @@ general_scalar_chain::compute_convert_gain ()
   if (dump_file)
     fprintf (dump_file, "  Instruction conversion gain: %d\n", gain);
 
-  /* ???  What about integer to SSE?  */
-  EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, insn_uid, bi)
-    cost += DF_REG_DEF_COUNT (insn_uid) * ix86_cost->sse_to_integer;
+  /* Cost the integer to sse and sse to integer moves.  */
+  cost += n_sse_to_integer * ix86_cost->sse_to_integer;
+  /* ???  integer_to_sse but we only have that in the RA cost table.
+     Assume sse_to_integer/integer_to_sse are the same which they
+     are at the moment.  */
+  cost += n_integer_to_sse * ix86_cost->sse_to_integer;
 
   if (dump_file)
     fprintf (dump_file, "  Registers conversion cost: %d\n", cost);
@@ -649,85 +678,64 @@ gen_gpr_to_xmm_move_src (enum machine_mode vmode, rtx gpr)
    and replace its uses in a chain.  */
 
 void
-general_scalar_chain::make_vector_copies (unsigned regno)
+general_scalar_chain::make_vector_copies (rtx_insn *insn, rtx reg)
 {
-  rtx reg = regno_reg_rtx[regno];
-  rtx vreg = gen_reg_rtx (smode);
-  df_ref ref;
-
-  defs_map.put (reg, vreg);
+  rtx vreg = *defs_map.get (reg);
 
-  /* For each insn defining REGNO, see if it is defined by an insn
-     not part of the chain but with uses in insns part of the chain
-     and insert a copy in that case.  */
-  for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref))
+  start_sequence ();
+  if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
     {
-      if (bitmap_bit_p (insns, DF_REF_INSN_UID (ref)))
-       continue;
-      df_link *use;
-      for (use = DF_REF_CHAIN (ref); use; use = use->next)
-       if (!DF_REF_REG_MEM_P (use->ref)
-           && bitmap_bit_p (insns, DF_REF_INSN_UID (use->ref)))
-         break;
-      if (!use)
-       continue;
-
-      start_sequence ();
-      if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
+      rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP);
+      if (smode == DImode && !TARGET_64BIT)
        {
-         rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP);
-         if (smode == DImode && !TARGET_64BIT)
-           {
-             emit_move_insn (adjust_address (tmp, SImode, 0),
-                             gen_rtx_SUBREG (SImode, reg, 0));
-             emit_move_insn (adjust_address (tmp, SImode, 4),
-                             gen_rtx_SUBREG (SImode, reg, 4));
-           }
-         else
-           emit_move_insn (copy_rtx (tmp), reg);
-         emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
-                                 gen_gpr_to_xmm_move_src (vmode, tmp)));
+         emit_move_insn (adjust_address (tmp, SImode, 0),
+                         gen_rtx_SUBREG (SImode, reg, 0));
+         emit_move_insn (adjust_address (tmp, SImode, 4),
+                         gen_rtx_SUBREG (SImode, reg, 4));
        }
-      else if (!TARGET_64BIT && smode == DImode)
+      else
+       emit_move_insn (copy_rtx (tmp), reg);
+      emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
+                             gen_gpr_to_xmm_move_src (vmode, tmp)));
+    }
+  else if (!TARGET_64BIT && smode == DImode)
+    {
+      if (TARGET_SSE4_1)
        {
-         if (TARGET_SSE4_1)
-           {
-             emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
-                                         CONST0_RTX (V4SImode),
-                                         gen_rtx_SUBREG (SImode, reg, 0)));
-             emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0),
-                                           gen_rtx_SUBREG (V4SImode, vreg, 0),
-                                           gen_rtx_SUBREG (SImode, reg, 4),
-                                           GEN_INT (2)));
-           }
-         else
-           {
-             rtx tmp = gen_reg_rtx (DImode);
-             emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
-                                         CONST0_RTX (V4SImode),
-                                         gen_rtx_SUBREG (SImode, reg, 0)));
-             emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0),
-                                         CONST0_RTX (V4SImode),
-                                         gen_rtx_SUBREG (SImode, reg, 4)));
-             emit_insn (gen_vec_interleave_lowv4si
-                        (gen_rtx_SUBREG (V4SImode, vreg, 0),
-                         gen_rtx_SUBREG (V4SImode, vreg, 0),
-                         gen_rtx_SUBREG (V4SImode, tmp, 0)));
-           }
+         emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
+                                     CONST0_RTX (V4SImode),
+                                     gen_rtx_SUBREG (SImode, reg, 0)));
+         emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0),
+                                       gen_rtx_SUBREG (V4SImode, vreg, 0),
+                                       gen_rtx_SUBREG (SImode, reg, 4),
+                                       GEN_INT (2)));
        }
       else
-       emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
-                               gen_gpr_to_xmm_move_src (vmode, reg)));
-      rtx_insn *seq = get_insns ();
-      end_sequence ();
-      rtx_insn *insn = DF_REF_INSN (ref);
-      emit_conversion_insns (seq, insn);
-
-      if (dump_file)
-       fprintf (dump_file,
-                "  Copied r%d to a vector register r%d for insn %d\n",
-                regno, REGNO (vreg), INSN_UID (insn));
+       {
+         rtx tmp = gen_reg_rtx (DImode);
+         emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
+                                     CONST0_RTX (V4SImode),
+                                     gen_rtx_SUBREG (SImode, reg, 0)));
+         emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0),
+                                     CONST0_RTX (V4SImode),
+                                     gen_rtx_SUBREG (SImode, reg, 4)));
+         emit_insn (gen_vec_interleave_lowv4si
+                    (gen_rtx_SUBREG (V4SImode, vreg, 0),
+                     gen_rtx_SUBREG (V4SImode, vreg, 0),
+                     gen_rtx_SUBREG (V4SImode, tmp, 0)));
+       }
     }
+  else
+    emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
+                           gen_gpr_to_xmm_move_src (vmode, reg)));
+  rtx_insn *seq = get_insns ();
+  end_sequence ();
+  emit_conversion_insns (seq, insn);
+
+  if (dump_file)
+    fprintf (dump_file,
+            "  Copied r%d to a vector register r%d for insn %d\n",
+            REGNO (reg), REGNO (vreg), INSN_UID (insn));
 }
 
 /* Copy the definition SRC of INSN inside the chain to DST for
@@ -1158,7 +1166,11 @@ general_scalar_chain::convert_registers ()
   bitmap_iterator bi;
   unsigned id;
   EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, id, bi)
-    make_vector_copies (id);
+    defs_map.put (regno_reg_rtx[id], gen_reg_rtx (smode));
+  EXECUTE_IF_SET_IN_BITMAP (insns_conv, 0, id, bi)
+    for (df_ref ref = DF_INSN_UID_DEFS (id); ref; ref = DF_REF_NEXT_LOC (ref))
+      if (bitmap_bit_p (defs_conv, DF_REF_REGNO (ref)))
+       make_vector_copies (DF_REF_INSN (ref), DF_REF_REAL_REG (ref));
 }
 
 /* Convert whole chain creating required register
index 8381efe..09fe340 100644 (file)
@@ -167,16 +167,19 @@ class scalar_chain
 class general_scalar_chain : public scalar_chain
 {
  public:
-  general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_)
-    : scalar_chain (smode_, vmode_) {}
+  general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_);
+  ~general_scalar_chain ();
   int compute_convert_gain ();
  private:
   hash_map<rtx, rtx> defs_map;
+  bitmap insns_conv;
+  unsigned n_sse_to_integer;
+  unsigned n_integer_to_sse;
   void mark_dual_mode_def (df_ref def);
   void convert_insn (rtx_insn *insn);
   void convert_op (rtx *op, rtx_insn *insn);
   void convert_reg (rtx_insn *insn, rtx dst, rtx src);
-  void make_vector_copies (unsigned regno);
+  void make_vector_copies (rtx_insn *, rtx);
   void convert_registers ();
   int vector_const_cost (rtx exp);
 };