At least on aarch64, modes_tieable_p is a stricter condition than
can_change_mode_class.  can_change_mode_class tells us whether the
subreg rules produce a sensible result for a particular mode change.
modes_tieable_p in addition tells us whether a mode change is
reasonable for optimisation purposes.

A false return from either hook should (and does) prevent early_ra
from attempting an allocation.  But only a false return from
can_change_mode_class should invalidate the liveness tracking;
we can still analyse subregs for which can_change_mode_class is
true and modes_tieable_p is false.

This doesn't make a difference on its own, but it helps later
patches.

gcc/
        * config/aarch64/aarch64-early-ra.cc
        (early_ra::get_allocno_subgroup): Split can_change_mode_class test
        out from modes_tieable_p test and only invalidate the live range
        information for the former.
---
 gcc/config/aarch64/aarch64-early-ra.cc | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-early-ra.cc 
b/gcc/config/aarch64/aarch64-early-ra.cc
index 68e96bd4da8..79ac7b099eb 100644
--- a/gcc/config/aarch64/aarch64-early-ra.cc
+++ b/gcc/config/aarch64/aarch64-early-ra.cc
@@ -1434,8 +1434,8 @@ early_ra::get_allocno_subgroup (rtx reg)
       if (!inner)
        return {};
 
-      if (!targetm.modes_tieable_p (GET_MODE (SUBREG_REG (reg)),
-                                   GET_MODE (reg)))
+      if (!targetm.can_change_mode_class (GET_MODE (SUBREG_REG (reg)),
+                                         GET_MODE (reg), FP_REGS))
        {
          record_live_range_failure ([&](){
            fprintf (dump_file, "cannot refer to r%d:%s in mode %s",
@@ -1446,6 +1446,15 @@ early_ra::get_allocno_subgroup (rtx reg)
          return {};
        }
 
+      if (!targetm.modes_tieable_p (GET_MODE (SUBREG_REG (reg)),
+                                   GET_MODE (reg)))
+       record_allocation_failure ([&](){
+           fprintf (dump_file, "r%d's mode %s is not tieable to mode %s",
+                    REGNO (SUBREG_REG (reg)),
+                    GET_MODE_NAME (GET_MODE (SUBREG_REG (reg))),
+                    GET_MODE_NAME (GET_MODE (reg)));
+       });
+
       subreg_info info;
       subreg_get_info (V0_REGNUM, GET_MODE (SUBREG_REG (reg)),
                       SUBREG_BYTE (reg), GET_MODE (reg), &info);
-- 
2.25.1

Reply via email to