[AArch64] Fix aarch64_ira_change_pseudo_allocno_class
authorWilco Dijkstra <wdijkstr@arm.com>
Wed, 30 May 2018 10:31:21 +0000 (10:31 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Wed, 30 May 2018 10:31:21 +0000 (10:31 +0000)
A recent commit removing '*' from the md files caused a large regression in
h264ref.  It turns out aarch64_ira_change_pseudo_allocno_class is no longer
effective after the SVE changes, and the combination results in the regression.
This patch fixes it by explicitly checking for a subset of GENERAL_REGS and
FP_REGS.  Add a missing ? to aarch64_get_lane to fix a failure in the testsuite.

    gcc/
* config/aarch64/aarch64.c (aarch64_ira_change_pseudo_allocno_class):
Check for subset of GENERAL_REGS and FP_REGS.
* config/aarch64/aarch64-simd.md (aarch64_get_lane): Increase cost of
r=w alternative.

From-SVN: r260951

gcc/ChangeLog
gcc/config/aarch64/aarch64-simd.md
gcc/config/aarch64/aarch64.c

index 51958e8c3b5c8b4eb41e87fc43aca4597a50945c..ef0a71e7145c56b641032558bb8e1f73f0027a6e 100644 (file)
@@ -1,3 +1,10 @@
+2018-05-30  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * config/aarch64/aarch64.c (aarch64_ira_change_pseudo_allocno_class):
+       Check for subset of GENERAL_REGS and FP_REGS.
+       * config/aarch64/aarch64-simd.md (aarch64_get_lane): Increase cost of
+       r=w alternative.
+
 2018-05-30  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * alias.c (adjust_offset_for_component_ref): Use poly_int_tree_p
index daaefdab8d0663d7610681de9ebdfd1e69cd4c8f..962386981afb94ba4039fd19dc298e122101dbeb 100644 (file)
 ;; is guaranteed so upper bits should be considered undefined.
 ;; RTL uses GCC vector extension indices throughout so flip only for assembly.
 (define_insn "aarch64_get_lane<mode>"
-  [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
+  [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=?r, w, Utv")
        (vec_select:<VEL>
          (match_operand:VALL_F16 1 "register_operand" "w, w, w")
          (parallel [(match_operand:SI 2 "immediate_operand" "i, i, i")])))]
index afc91850d6f1458459f64bff0c8dfa3419d5e588..1fbde469ac173f67ac5adfc0d42d6694f2cb8a5c 100644 (file)
@@ -1087,16 +1087,17 @@ aarch64_err_no_fpadvsimd (machine_mode mode, const char *msg)
 }
 
 /* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS.
-   The register allocator chooses ALL_REGS if FP_REGS and GENERAL_REGS have
-   the same cost even if ALL_REGS has a much larger cost.  ALL_REGS is also
-   used if the cost of both FP_REGS and GENERAL_REGS is lower than the memory
-   cost (in this case the best class is the lowest cost one).  Using ALL_REGS
-   irrespectively of its cost results in bad allocations with many redundant
-   int<->FP moves which are expensive on various cores.
-   To avoid this we don't allow ALL_REGS as the allocno class, but force a
-   decision between FP_REGS and GENERAL_REGS.  We use the allocno class if it
-   isn't ALL_REGS.  Similarly, use the best class if it isn't ALL_REGS.
-   Otherwise set the allocno class depending on the mode.
+   The register allocator chooses POINTER_AND_FP_REGS if FP_REGS and
+   GENERAL_REGS have the same cost - even if POINTER_AND_FP_REGS has a much
+   higher cost.  POINTER_AND_FP_REGS is also used if the cost of both FP_REGS
+   and GENERAL_REGS is lower than the memory cost (in this case the best class
+   is the lowest cost one).  Using POINTER_AND_FP_REGS irrespectively of its
+   cost results in bad allocations with many redundant int<->FP moves which
+   are expensive on various cores.
+   To avoid this we don't allow POINTER_AND_FP_REGS as the allocno class, but
+   force a decision between FP_REGS and GENERAL_REGS.  We use the allocno class
+   if it isn't POINTER_AND_FP_REGS.  Similarly, use the best class if it isn't
+   POINTER_AND_FP_REGS.  Otherwise set the allocno class depending on the mode.
    The result of this is that it is no longer inefficient to have a higher
    memory move cost than the register move cost.
 */
@@ -1107,10 +1108,12 @@ aarch64_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class,
 {
   machine_mode mode;
 
-  if (allocno_class != ALL_REGS)
+  if (reg_class_subset_p (allocno_class, GENERAL_REGS)
+      || reg_class_subset_p (allocno_class, FP_REGS))
     return allocno_class;
 
-  if (best_class != ALL_REGS)
+  if (reg_class_subset_p (best_class, GENERAL_REGS)
+      || reg_class_subset_p (best_class, FP_REGS))
     return best_class;
 
   mode = PSEUDO_REGNO_MODE (regno);