aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2024-11-18 19:32:49 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2024-11-18 19:32:49 +0000
commit716aa5a668388a09b27525dce847d8d36c4c2fab (patch)
tree48f8f5d72d0addce28c6b682b63cb03f9fa48046
parent4712ecde4869cf29c40a7df44e4655939d90d4d8 (diff)
downloadgcc-716aa5a668388a09b27525dce847d8d36c4c2fab.zip
gcc-716aa5a668388a09b27525dce847d8d36c4c2fab.tar.gz
gcc-716aa5a668388a09b27525dce847d8d36c4c2fab.tar.bz2
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.
-rw-r--r--gcc/config/aarch64/aarch64-early-ra.cc39
1 files changed, 37 insertions, 2 deletions
diff --git a/gcc/config/aarch64/aarch64-early-ra.cc b/gcc/config/aarch64/aarch64-early-ra.cc
index d6ed7fe..bf8827f 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 {};
}