https://gcc.gnu.org/g:716aa5a668388a09b27525dce847d8d36c4c2fab

commit r15-5419-g716aa5a668388a09b27525dce847d8d36c4c2fab
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Mon Nov 18 19:32:49 2024 +0000

    aarch64: Add early_ra::record_live_range_failure
    
    So far, early_ra has used a single m_allocation_successful bool
    to record whether the current region is still being allocated.
    But there are (at least) two reasons why we might pull out of
    attempting an allocation:
    
    (1) We can't track the liveness of individual FP allocnos,
        due to some awkward subregs.
    
    (2) We're afraid of doing a worse job than the proper allocator.
    
    A later patch needs to distinguish (1) from other reasons, since
    (1) means that the liveness information is not trustworthy.
    (Currently we assume it is not trustworthy whenever
    m_allocation_successful is false, but that's too conservative.)
    
    gcc/
            * config/aarch64/aarch64-early-ra.cc
            (early_ra::record_live_range_failure): New member function.
            (early_ra::m_accurate_live_ranges): New member variable.
            (early_ra::start_new_region): Set m_accurate_live_ranges to true.
            (early_ra::get_allocno_subgroup): Use record_live_range_failure
            to abort the allocation on invalid subregs.

Diff:
---
 gcc/config/aarch64/aarch64-early-ra.cc | 39 ++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-early-ra.cc 
b/gcc/config/aarch64/aarch64-early-ra.cc
index d6ed7fee48b6..bf8827f33427 100644
--- a/gcc/config/aarch64/aarch64-early-ra.cc
+++ b/gcc/config/aarch64/aarch64-early-ra.cc
@@ -439,6 +439,9 @@ private:
 
   void start_new_region ();
 
+  template<typename T>
+  void record_live_range_failure (T);
+
   allocno_group_info *create_allocno_group (unsigned int, unsigned int);
   allocno_subgroup get_allocno_subgroup (rtx);
   void record_fpr_use (unsigned int);
@@ -551,6 +554,10 @@ private:
   // current function.
   unsigned int m_call_preserved_fprs;
 
+  // True if we have so far been able to track the live ranges of individual
+  // allocnos.
+  bool m_accurate_live_ranges;
+
   // True if we haven't yet failed to allocate the current region.
   bool m_allocation_successful;
 
@@ -1314,10 +1321,30 @@ early_ra::start_new_region ()
   m_dead_insns.truncate (0);
   m_allocated_fprs = 0;
   m_call_preserved_fprs = 0;
+  m_accurate_live_ranges = true;
   m_allocation_successful = true;
   m_current_region += 1;
 }
 
+// Record that we can no longer track the liveness of individual allocnos.
+// Call DUMP to dump the reason to a dump file.
+template<typename T>
+void
+early_ra::record_live_range_failure (T dump)
+{
+  if (!m_accurate_live_ranges)
+    return;
+
+  m_accurate_live_ranges = false;
+  m_allocation_successful = false;
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Unable to track live ranges further: ");
+      dump ();
+      fprintf (dump_file, "\n");
+    }
+}
+
 // Create and return an allocno group of size SIZE for register REGNO.
 // REGNO can be INVALID_REGNUM if the group just exists to allow
 // other groups to be chained together, and does not have any new
@@ -1390,7 +1417,12 @@ early_ra::get_allocno_subgroup (rtx reg)
       if (!targetm.modes_tieable_p (GET_MODE (SUBREG_REG (reg)),
                                    GET_MODE (reg)))
        {
-         m_allocation_successful = false;
+         record_live_range_failure ([&](){
+           fprintf (dump_file, "cannot refer to r%d:%s in mode %s",
+                    REGNO (SUBREG_REG (reg)),
+                    GET_MODE_NAME (GET_MODE (SUBREG_REG (reg))),
+                    GET_MODE_NAME (GET_MODE (reg)));
+         });
          return {};
        }
 
@@ -1399,7 +1431,10 @@ early_ra::get_allocno_subgroup (rtx reg)
                       SUBREG_BYTE (reg), GET_MODE (reg), &info);
       if (!info.representable_p)
        {
-         m_allocation_successful = false;
+         record_live_range_failure ([&](){
+           fprintf (dump_file, "subreg of r%d is invalid for V0",
+                    REGNO (SUBREG_REG (reg)));
+         });
          return {};
        }

Reply via email to